Program runs until it tries to access the SharedPreferences in my updateUserSettings() method. I have spent the last 2 hours searching the internet with no explanations. Please help!
I have the line that messes everything up Commented at the bottom of my onCreate();
Here is FuelEconomyCalculatorActivity.java
package com.example.fuelcalculator;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
public class FuelEconomyCalculatorActivity extends ActionBarActivity implements
OnClickListener {
private EditText fuelEditText;
private EditText distanceEditText;
private TextView mpgTextView;
private TextView litresTextView;
private Button calculateButton;
private Button clearButton;
private RadioButton gallonsRadio;
private RadioButton litresRadio;
private RadioButton milesRadio;
private RadioButton kmRadio;
private String mpg = " ";
private String kp100 = " ";
private boolean metricChecked;
private boolean imperialChecked;
private boolean usGallonChecked;
private boolean ukGallonChecked;
private static final int RESULT_SETTINGS = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fuel_economy_calculator);
fuelEditText = (EditText) findViewById(R.id.fuelEditText);
distanceEditText = (EditText) findViewById(R.id.distanceEditText);
mpgTextView = (TextView) findViewById(R.id.mpgTextView);
litresTextView = (TextView) findViewById(R.id.litresTextView);
calculateButton = (Button) findViewById(R.id.calculateButton);
clearButton = (Button) findViewById(R.id.clearButton);
gallonsRadio = (RadioButton) findViewById(R.id.gallonsRadio);
litresRadio = (RadioButton) findViewById(R.id.litresRadio);
milesRadio = (RadioButton) findViewById(R.id.milesRadio);
kmRadio = (RadioButton) findViewById(R.id.kmRadio);
calculateButton.setOnClickListener(this);
clearButton.setOnClickListener(this);
if (savedInstanceState != null) {
mpg = savedInstanceState.getString("mpg");
kp100 = savedInstanceState.getString("kp100");
initializeViews();
}
// updateUserSettings();
}
protected void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString("mpg", (String) mpgTextView.getText());
savedInstanceState.putString("kp100", (String) litresTextView.getText());
litresRadio.setChecked(true);
kmRadio.setChecked(true);
}
private void initializeViews() {
mpgTextView.setText(mpg);
litresTextView.setText(kp100);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.fuel_economy_calculator, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.action_settings: {
Intent intent = new Intent(FuelEconomyCalculatorActivity.this,
FuelEconomySettingsActivity.class);
startActivityForResult(intent, RESULT_SETTINGS);
return true;
}
case R.id.action_about: {
Intent intent = new Intent(getApplicationContext(), FuelEconomyAboutPageActivity.class);
startActivity(intent);
return true;
}
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case RESULT_SETTINGS:
updateUserSettings();
break;
}
}
private void updateUserSettings() {
SharedPreferences sharedPrefs = PreferenceManager
.getDefaultSharedPreferences(this);
if(sharedPrefs.getString("measuringUnits", null).equalsIgnoreCase("metric"))
{
metricChecked = true;
imperialChecked = false;
}
else if(sharedPrefs.getString("measuringUnits", null).equalsIgnoreCase("imperial"))
{
imperialChecked = true;
metricChecked = false;
}
if(sharedPrefs.getString("gallons", null).equalsIgnoreCase("uk"))
{
ukGallonChecked = true;
usGallonChecked = false;
}
else if(sharedPrefs.getString("gallons", null).equalsIgnoreCase("us"))
{
usGallonChecked = true;
ukGallonChecked = false;
}
if(metricChecked)
{
litresRadio.setChecked(true);
kmRadio.setChecked(true);
}
else if(imperialChecked)
{
milesRadio.setChecked(true);
gallonsRadio.setChecked(true);
}
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.calculateButton) {
float mpg = 0;
float kmLitres = 0;
// it doesn't matter which you use here, as long
// as you use a fuel and a distance method
if (ukGallonChecked && !usGallonChecked) {
if (getKM() > 0 && getLitres() > 0) {
mpg = getMiles() / getGallons();
kmLitres = getLitres() / (getKM() / 100);
mpgTextView.setText(String.format("%.2f", mpg));
litresTextView.setText(String.format("%.2f", kmLitres));
}
} else if (usGallonChecked && !ukGallonChecked) {
if (getKM() > 0 && getLitres() > 0) {
mpg = getMiles() / getGallonsUS();
kmLitres = getLitresUS() / (getKM() / 100);
mpgTextView.setText(String.format("%.2f", mpg));
litresTextView.setText(String.format("%.2f", kmLitres));
}
}
} else if (v.getId() == R.id.clearButton) {
resetValues();
}
}
public float CheckValues(EditText input) {
float value = 0;
try {
value = Float.parseFloat(input.getText().toString());
if (value < 1) {
Toast toast = Toast.makeText(this,
"Please enter a number that is larger than 0",
Toast.LENGTH_SHORT);
toast.show();
}
} catch (Exception ex) {
Toast toast = Toast.makeText(this, "Please enter a number",
Toast.LENGTH_SHORT);
toast.show();
}
return value;
}
public void resetValues() {
mpg = " ";
kp100 = " ";
fuelEditText.setText("");
distanceEditText.setText("");
mpgTextView.setText("");
litresTextView.setText("");
}
public float getKM() {
float distance = CheckValues(distanceEditText);
if (milesRadio.isChecked()) {
distance = (float) (distance * 1.60934);
}
return distance;
}
public float getMiles() {
float distance = CheckValues(distanceEditText);
if (kmRadio.isChecked()) {
distance = (float) (distance * 0.62137);
}
return distance;
}
public float getLitres() {
float fuel = CheckValues(fuelEditText);
if (gallonsRadio.isChecked()) {
fuel = (float) (fuel * 4.54609);
}
return fuel;
}
public float getLitresUS() {
float fuel = CheckValues(fuelEditText);
if (gallonsRadio.isChecked()) {
fuel = (float) (fuel * 3.785411784);
}
return fuel;
}
public float getGallons() {
float fuel = CheckValues(fuelEditText);
if (litresRadio.isChecked()) {
fuel = (float) (fuel * 0.219969);
}
return fuel;
}
public float getGallonsUS() {
float fuel = CheckValues(fuelEditText);
if (litresRadio.isChecked()) {
fuel = (float) (fuel * 0.264172);
}
return fuel;
}
}
And here is my FuelEconomySettingsActivity.java
package com.example.fuelcalculator;
import android.app.Activity;
import android.os.Bundle;
public class FuelEconomySettingsActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content,
new FuelEconomySettingsFragment()).commit();
}
}
Here is my LogCat
07-18 14:35:37.014: E/AndroidRuntime(3084): FATAL EXCEPTION: main
07-18 14:35:37.014: E/AndroidRuntime(3084): Process: com.example.fuelcalculator, PID: 3084
07-18 14:35:37.014: E/AndroidRuntime(3084): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fuelcalculator/com.example.fuelcalculator.FuelEconomyCalculatorActivity}: java.lang.NullPointerException
07-18 14:35:37.014: E/AndroidRuntime(3084): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
07-18 14:35:37.014: E/AndroidRuntime(3084): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
07-18 14:35:37.014: E/AndroidRuntime(3084): at android.app.ActivityThread.access$900(ActivityThread.java:161)
07-18 14:35:37.014: E/AndroidRuntime(3084): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
07-18 14:35:37.014: E/AndroidRuntime(3084): at android.os.Handler.dispatchMessage(Handler.java:102)
07-18 14:35:37.014: E/AndroidRuntime(3084): at android.os.Looper.loop(Looper.java:157)
07-18 14:35:37.014: E/AndroidRuntime(3084): at android.app.ActivityThread.main(ActivityThread.java:5356)
07-18 14:35:37.014: E/AndroidRuntime(3084): at java.lang.reflect.Method.invokeNative(Native Method)
07-18 14:35:37.014: E/AndroidRuntime(3084): at java.lang.reflect.Method.invoke(Method.java:515)
07-18 14:35:37.014: E/AndroidRuntime(3084): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
07-18 14:35:37.014: E/AndroidRuntime(3084): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
07-18 14:35:37.014: E/AndroidRuntime(3084): at dalvik.system.NativeStart.main(Native Method)
07-18 14:35:37.014: E/AndroidRuntime(3084): Caused by: java.lang.NullPointerException
07-18 14:35:37.014: E/AndroidRuntime(3084): at com.example.fuelcalculator.FuelEconomyCalculatorActivity.updateUserSettings(FuelEconomyCalculatorActivity.java:128)
07-18 14:35:37.014: E/AndroidRuntime(3084): at com.example.fuelcalculator.FuelEconomyCalculatorActivity.onCreate(FuelEconomyCalculatorActivity.java:63)
07-18 14:35:37.014: E/AndroidRuntime(3084): at android.app.Activity.performCreate(Activity.java:5426)
07-18 14:35:37.014: E/AndroidRuntime(3084): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
07-18 14:35:37.014: E/AndroidRuntime(3084): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
07-18 14:35:37.014: E/AndroidRuntime(3084): ... 11 more
I am new to Android so I am not very good at debugging so could someone please assist me with my predicament?
The activity is already included in my Manifest so I know that is not the issue.
Any help is much obliged.
You are getting a NullPointerException because you are getting null as the default value for SharedPreference.getString()
Since it is getString() get an empty string as the default value...
So try this..
if(sharedPrefs.getString("measuringUnits", "").equalsIgnoreCase("metric"))
instead of
if(sharedPrefs.getString("measuringUnits", null).equalsIgnoreCase("metric"))
Related
I'm a new programmer,recently i have a bug but can't solve
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.Bl
uetoothChat/com.example.android.BluetoothFileTran.FileTranActivity}:
java.lang.NullPointerException
logcat stack trace
04-26 10:19:43.613: E/BluetoothChat(21754): +++ ON CREATE +++
04-26 10:19:44.213: E/CheckPermission(21754): _bluetooth code = 1
04-26 10:19:44.213: E/BluetoothChat(21754): ++ ON START ++
04-26 10:19:44.233: E/BluetoothChat(21754): + ON RESUME +
04-26 10:19:44.233: E/CheckPermission(21754): _bluetooth code = 13
04-26 10:19:45.643: E/BluetoothChat(21754): - ON PAUSE -
04-26 10:19:47.223: E/BluetoothChat(21754): + ON RESUME +
04-26 10:19:55.093: E/BluetoothChat(21754): - ON PAUSE -
04-26 10:20:21.363: E/AndroidRuntime(21754): FATAL EXCEPTION: main
04-26 10:20:21.363: E/AndroidRuntime(21754): Process: com.example.android.BluetoothChat, PID: 21754
04-26 10:20:21.363: E/AndroidRuntime(21754): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.BluetoothChat/com.example.android.BluetoothFileTran.FileTranActivity}: java.lang.NullPointerException
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2190)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread.access$800(ActivityThread.java:139)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.os.Handler.dispatchMessage(Handler.java:102)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.os.Looper.loop(Looper.java:136)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread.main(ActivityThread.java:5049)
04-26 10:20:21.363: E/AndroidRuntime(21754): at java.lang.reflect.Method.invokeNative(Native Method)
04-26 10:20:21.363: E/AndroidRuntime(21754): at java.lang.reflect.Method.invoke(Method.java:515)
04-26 10:20:21.363: E/AndroidRuntime(21754): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:818)
04-26 10:20:21.363: E/AndroidRuntime(21754): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:634)
04-26 10:20:21.363: E/AndroidRuntime(21754): at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
04-26 10:20:21.363: E/AndroidRuntime(21754): at dalvik.system.NativeStart.main(Native Method)
04-26 10:20:21.363: E/AndroidRuntime(21754): Caused by: java.lang.NullPointerException
04-26 10:20:21.363: E/AndroidRuntime(21754): at com.example.android.BluetoothFileTran.FileTranActivity.onCreate(FileTranActivity.java:66)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.Activity.performCreate(Activity.java:5293)
04-26 10:20:21.363: E/AndroidRuntime(21754): at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
04-26 10:20:21.363: E/AndroidRuntime(21754): at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:631)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.Activity.performCreate(Native Method)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
04-26 10:20:21.363: E/AndroidRuntime(21754): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2154)
04-26 10:20:21.363: E/AndroidRuntime(21754): ... 12 more
here is Bluetoooth.java
package com.example.android.BluetoothChat;
import com.example.android.BluetoothChat.R;
import com.example.android.BluetoothChat.service.BluetoothChatService;
import com.example.android.BluetoothFileTran.FileTranActivity;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class BluetoothChat extends Activity {
public static final String SEND_FILE_NAME = "sendFileName";
public static final int REQUEST_FILE = 1000;
private static String mSendFileName ;
private Handler mOthHandler;
private static String mAddress ;
private static final String TAG = "BluetoothChat";
private static final boolean D = true;
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
private ListView mConversationView;
private EditText mOutEditText;
private Button mSendButton;
private String mConnectedDeviceName = null;
private ArrayAdapter<String> mConversationArrayAdapter;
private StringBuffer mOutStringBuffer;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothChatService mChatService = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(D) Log.e(TAG, "+++ ON CREATE +++");
setContentView(R.layout.main);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
}
#Override
public void onStart() {
super.onStart();
if(D) Log.e(TAG, "++ ON START ++");
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
} else {
if (mChatService == null) setupChat();
}
}
private void setupChat() {
Log.d(TAG, "setupChat()");
mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
mConversationView = (ListView) findViewById(R.id.in);
mConversationView.setAdapter(mConversationArrayAdapter);
mOutEditText = (EditText) findViewById(R.id.edit_text_out);
mOutEditText.setOnEditorActionListener(mWriteListener);
mSendButton = (Button) findViewById(R.id.button_send);
mSendButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
TextView view = (TextView) findViewById(R.id.edit_text_out);
String message = view.getText().toString();
sendMessage(message);
}
});
mChatService = new BluetoothChatService(this, mHandler);
mOutStringBuffer = new StringBuffer("");
}
#Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
if (mChatService != null) {
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
mChatService.start();
}
}
}
private TextView.OnEditorActionListener mWriteListener =
new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
//EditorInfo.IME_NULL KeyEvent.ACTION_UP
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
String message = view.getText().toString();
sendMessage(message);
}
if(D) Log.i(TAG, "END onEditorAction");
return true;
}
};
#Override
public synchronized void onPause() {
super.onPause();
if(D) Log.e(TAG, "- ON PAUSE -");
}
#Override
public void onStop() {
super.onStop();
if(D) Log.e(TAG, "-- ON STOP --");
}
#Override
public void onDestroy() {
super.onDestroy();
if (mChatService != null) mChatService.stop();
if(D) Log.e(TAG, "--- ON DESTROY ---");
}
private void sendMessage(String message) {
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
if (message.length() > 0) {
byte[] send = message.getBytes();
mChatService.write(send);
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case BluetoothChatService.STATE_CONNECTED:
mConversationArrayAdapter.clear();
break;
case BluetoothChatService.STATE_CONNECTING:
break;
case BluetoothChatService.STATE_LISTEN:
case BluetoothChatService.STATE_NONE:
break;
}
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
String writeMessage = new String(writeBuf);
mConversationArrayAdapter.add("Me: " + writeMessage);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(readBuf, 0, msg.arg1);
mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage);
break;
case MESSAGE_DEVICE_NAME:
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
// mAddress = msg.getData().getString(DEVICE_ADDRESS);
Toast.makeText(getApplicationContext(), "Connected to "
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
Toast.LENGTH_SHORT).show();
break;
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(D) Log.d(TAG, "onActivityResult " + resultCode);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
if (resultCode == Activity.RESULT_OK) {
mAddress = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mAddress);
mChatService.connect(device);
}
break;
case REQUEST_ENABLE_BT:
if (resultCode == Activity.RESULT_OK) {
setupChat();
} else {
Log.d(TAG, "BT not enabled");
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
}
break;
case REQUEST_FILE:
if (resultCode == Activity.RESULT_OK) {
mSendFileName = data.getExtras().getString(SEND_FILE_NAME);
doSendFileByBluetooth();
}
break;
}
}
private void doSendFileByBluetooth() {
String filePath = mSendFileName.trim();
if(!filePath.equals("null")){
if(null == mOthHandler){
HandlerThread handlerThread = new HandlerThread("other_thread");
handlerThread.start();
mOthHandler = new Handler(handlerThread.getLooper());
}
mOthHandler.post(new Runnable() {
#Override
public void run() {
ContentValues cv = new ContentValues();
String uri = "file://" + mSendFileName.trim();
cv.put("uri", uri);
cv.put("destination", mAddress.trim());
cv.put("direction", 0);
Long ts = System.currentTimeMillis();
cv.put("timestamp", ts);
getContentResolver().insert(Uri.parse("content://com.android.bluetooth.opp/btopp"), cv);
}
});
}else {
Toast.makeText(BluetoothChat.this, "请选择要发送的文件!", Toast.LENGTH_LONG).show();
}
}
private void ensureDiscoverable() {
if(D) Log.d(TAG, "ensure discoverable");
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.option_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.scan:
Intent serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
return true;
case R.id.discoverable:
ensureDiscoverable();
return true;
case R.id.file_transport:
Intent fileIntent = new Intent(this, FileTranActivity.class);
startActivityForResult(fileIntent, REQUEST_FILE);
return true;
}
return false;
}
}
here is FileTranActivity.java
package com.example.android.BluetoothFileTran;
import java.io.File;
import com.example.android.BluetoothChat.BluetoothChat;
import com.example.android.BluetoothChat.R;
import com.example.android.BluetoothFileTran.adapter.AdapterManager;
import com.example.android.BluetoothFileTran.adapter.FileListAdapter;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class FileTranActivity extends Activity {
ListView mFileListView;
FileListAdapter mFileListAdapter;
AdapterManager mAdapterManager;
private Handler mOtherHandler;
private Runnable updateFileListRunnable;
private File file;
private String sdcardPath;
private String path;
Button mBackBtn;
Button mEnsureBtn;
Button mCancelBtn;
TextView mLastClickView;
TextView mNowClickView;
private boolean isSelected = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.file_list);
setResult(Activity.RESULT_CANCELED);
mFileListView = (ListView) findViewById(R.id.fileListView);
mBackBtn = (Button) findViewById(R.id.selectFileBackBtn);
mEnsureBtn = (Button) findViewById(R.id.selectFileEnsureBtn);
mCancelBtn = (Button) findViewById(R.id.selectFileCancelBtn);
sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();
path = sdcardPath;
mAdapterManager = BluetoothApplication.getInstance().getAdapterManager();
mFileListView.setAdapter(mAdapterManager.getFileListAdapter());
mAdapterManager.updateFileListAdapter(path);
mFileListView.setOnItemClickListener(mFileListOnItemClickListener);
mBackBtn.setOnClickListener(mBackBtnClickListener);
mEnsureBtn.setOnClickListener(mEnsureBtnClickListener);
mCancelBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FileTranActivity.this.finish();
}
});
}
private OnItemClickListener mFileListOnItemClickListener = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
file = (File) mFileListView.getAdapter().getItem(position);
if(file.isFile()){
if(null != mLastClickView){
mLastClickView.setTextColor(Color.WHITE);
}
mNowClickView = (TextView) view.findViewById(R.id.fileNameTV);
mNowClickView.setTextColor(Color.BLUE);
isSelected = true;
mLastClickView = mNowClickView;
}else {
path = file.getAbsolutePath();
updateFileList();
}
}
};
private OnClickListener mBackBtnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
if(path.equals(sdcardPath)){
return ;
}
path = path.substring(0, path.lastIndexOf("/"));
updateFileList();
}
};
private OnClickListener mEnsureBtnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
if(!isSelected){
Toast.makeText(FileTranActivity.this, "请选择文件!", Toast.LENGTH_LONG).show();
return ;
}
Intent intent = new Intent();
intent.putExtra(BluetoothChat.SEND_FILE_NAME, file.getAbsolutePath());
setResult(Activity.RESULT_OK, intent);
FileTranActivity.this.finish();
}
};
private void updateFileList() {
if(null != mLastClickView){
mLastClickView.setTextColor(Color.WHITE);
mLastClickView = null;
isSelected = false;
}
if(null == updateFileListRunnable){
updateFileListRunnable = new Runnable() {
#Override
public void run() {
mAdapterManager.updateFileListAdapter(path);
}
};
}
if(null == mOtherHandler){
HandlerThread handlerThread = new HandlerThread("other_thread");
handlerThread.start();
mOtherHandler = new Handler(handlerThread.getLooper());
}
mOtherHandler.post(updateFileListRunnable);
}
}
then ,I find it point out the error in the FileTranActivity.java
mAdapterManager = BluetoothApplication.getInstance().getAdapterManager();
so ,here is BluetoothApplication.java
package com.example.android.BluetoothFileTran;
import com.example.android.BluetoothFileTran.adapter.AdapterManager;
import com.example.android.BluetoothFileTran.adapter.util.TouchObject;
import android.app.Application;
public class BluetoothApplication extends Application {
private static BluetoothApplication application;
private AdapterManager mAdapterManager;
private TouchObject mTouchObject;
#Override
public void onCreate() {
super.onCreate();
if(null == application){
application = this;
}
mTouchObject = new TouchObject();
}
public static BluetoothApplication getInstance(){
return application;
}
public AdapterManager getAdapterManager() {
return mAdapterManager;
}
public void setAdapterManager(AdapterManager adapterManager) {
this.mAdapterManager = adapterManager;
}
public TouchObject getTouchObject() {
return mTouchObject;
}
public void setTouchObject(TouchObject touchObject) {
this.mTouchObject = touchObject;
}
}
and AdapterManager.java
package com.example.android.BluetoothFileTran.adapter;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Handler;
import com.example.android.BluetoothChat.R;
import com.example.android.BluetoothFileTran.adapter.FileListAdapter;
public class AdapterManager {
private Context mContext;
private FileListAdapter mFileListAdapter;
private List<BluetoothDevice> mDeviceList;
private List<File> mFileList;
private Handler mainHandler;
public AdapterManager(Context context){
this.mContext = context;
}
public FileListAdapter getFileListAdapter(){
if(null == mFileListAdapter){
mFileList = new ArrayList<File>();
mFileListAdapter = new FileListAdapter(mContext, mFileList, R.layout.file_list_item);
}
return mFileListAdapter;
}
public void clearDevice(){
if(null != mDeviceList){
mDeviceList.clear();
}
}
public void addDevice(BluetoothDevice bluetoothDevice){
mDeviceList.add(bluetoothDevice);
}
public void changeDevice(int listId, BluetoothDevice bluetoothDevice){
mDeviceList.remove(listId);
mDeviceList.add(listId, bluetoothDevice);
}
public void updateFileListAdapter(String path){
mFileList.clear();
mFileList.addAll(getFileList(path));
if(null == mainHandler){
mainHandler = new Handler(mContext.getMainLooper());
}
mainHandler.post(new Runnable() {
#Override
public void run() {
mFileListAdapter.notifyDataSetChanged();
}
});
}
public List<BluetoothDevice> getDeviceList() {
return mDeviceList;
}
public static List<File> getFileList(String path){
List<File> fileList = new ArrayList<File>();
File[] files = new File(path).listFiles();
if(files.length > 0){
List<File> allFolder = new ArrayList<File>();
List<File> allFile = new ArrayList<File>();
for(File file : files){
if(file.isFile()){
allFile.add(file);
}else {
allFolder.add(file);
}
}
fileList.addAll(allFolder);
fileList.addAll(allFile);
}
return fileList;
}
}
my xml is
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.BluetoothChat"
android:versionCode="1"
android:versionName="1.0" xmlns:tools="http://schemas.android.com/tools">
<uses-sdk
android:minSdkVersion="6"
android:targetSdkVersion="18" tools:ignore="OldTargetApi"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:label="#string/app_name"
android:icon="#drawable/ic_launcher"
android:theme="#style/AppTheme" >
<activity android:name="com.example.android.BluetoothChat.BluetoothChat"
android:label="#string/app_name"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.example.android.BluetoothChat.DeviceListActivity"
android:label="#string/select_device"
android:theme="#android:style/Theme.Dialog"
/>
<activity android:name="com.example.android.BluetoothFileTran.FileTranActivity"
android:label="#string/select_file"
android:theme="#android:style/Theme.Dialog"
/>
</application>
</manifest>
Register in the AndroidManifest the BluetoothFileTran class as application name in application tag:
<application
android:allowBackup="true"
android:name="com.example.android.BluetoothFileTran"
...
Without this, the BluetoothFileTran will not be loaded, and onCreate will never invoked.
This will return a null reference in BluetoothApplication.getInstance(), which are causing your NullPointerException.
Reference
Notice: Your package in manifest, package="com.example.android.BluetoothChat" is different from the package that BluetoothFileTran is located (not in one of childs). I recommend you to use the package com.example.android instead of com.example.android.BluetoothChat in manifest tag.
So I'm following along with a Lynda.com Tutorial on using Google Maps V2 to build mobile Apps and I was going along with a part that has you creating a map app that is finding the location programatically rather than relying on the setMyLocationEnabled(true) method. So I've followed along with the code and each time I go to run the app it crashes and give me the following error in the logcat:
05-15 12:18:35.139: E/AndroidRuntime(22270): FATAL EXCEPTION: main
05-15 12:18:35.139: E/AndroidRuntime(22270): Process: com.example.gmapsapp, PID: 22270
05-15 12:18:35.139: E/AndroidRuntime(22270): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.gmapsapp/com.example.gmapsapp.MainActivity}: java.lang.ClassCastException: com.example.gmapsapp.MainActivity cannot be cast to com.google.android.gms.common.GooglePlayServicesClient$ConnectionCallbacks
05-15 12:18:35.139: E/AndroidRuntime(22270): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
05-15 12:18:35.139: E/AndroidRuntime(22270): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
05-15 12:18:35.139: E/AndroidRuntime(22270): at android.app.ActivityThread.access$900(ActivityThread.java:161)
05-15 12:18:35.139: E/AndroidRuntime(22270): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
05-15 12:18:35.139: E/AndroidRuntime(22270): at android.os.Handler.dispatchMessage(Handler.java:102)
05-15 12:18:35.139: E/AndroidRuntime(22270): at android.os.Looper.loop(Looper.java:157)
05-15 12:18:35.139: E/AndroidRuntime(22270): at android.app.ActivityThread.main(ActivityThread.java:5356)
05-15 12:18:35.139: E/AndroidRuntime(22270): at java.lang.reflect.Method.invokeNative(Native Method)
05-15 12:18:35.139: E/AndroidRuntime(22270): at java.lang.reflect.Method.invoke(Method.java:515)
05-15 12:18:35.139: E/AndroidRuntime(22270): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
05-15 12:18:35.139: E/AndroidRuntime(22270): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
05-15 12:18:35.139: E/AndroidRuntime(22270): at dalvik.system.NativeStart.main(Native Method)
05-15 12:18:35.139: E/AndroidRuntime(22270): Caused by: java.lang.ClassCastException: com.example.gmapsapp.MainActivity cannot be cast to com.google.android.gms.common.GooglePlayServicesClient$ConnectionCallbacks
05-15 12:18:35.139: E/AndroidRuntime(22270): at com.example.gmapsapp.MainActivity.onCreate(MainActivity.java:60)
05-15 12:18:35.139: E/AndroidRuntime(22270): at android.app.Activity.performCreate(Activity.java:5426)
05-15 12:18:35.139: E/AndroidRuntime(22270): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
05-15 12:18:35.139: E/AndroidRuntime(22270): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
05-15 12:18:35.139: E/AndroidRuntime(22270): ... 11 more
Here's the code in my MainActivity.java, let me know if you need any other files to see if you can help with the issue thanks:
package com.example.gmapsapp;
import java.io.IOException;
import java.util.List;
import android.app.Dialog;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
public class MainActivity extends FragmentActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
private static final int GPS_ERRORDIALOG_REQUEST = 9001;
#SuppressWarnings("unused")
private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9002;
GoogleMap mMap;
#SuppressWarnings("unused")
private static final double SEATTLE_LAT = 47.60621,
SEATTLE_LNG =-122.33207,
SYDNEY_LAT = -33.867487,
SYDNEY_LNG = 151.20699,
NEWYORK_LAT = 40.714353,
NEWYORK_LNG = -74.005973;
private static final float DEFAULTZOOM = 15;
#SuppressWarnings("unused")
private static final String LOGTAG = "Maps";
LocationClient mLocationClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (servicesOK()) {
setContentView(R.layout.activity_map);
if (initMap()) {
// mMap.setMyLocationEnabled(true);
mLocationClient = new LocationClient(this, (ConnectionCallbacks) this, this);
mLocationClient.connect();
}
else {
Toast.makeText(this, "Map not available!", Toast.LENGTH_SHORT).show();
}
}
else {
setContentView(R.layout.activity_main);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public boolean servicesOK() {
int isAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (isAvailable == ConnectionResult.SUCCESS) {
return true;
}
else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)) {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(isAvailable, this, GPS_ERRORDIALOG_REQUEST);
dialog.show();
}
else {
Toast.makeText(this, "Can't connect to Google Play services", Toast.LENGTH_SHORT).show();
}
return false;
}
private boolean initMap() {
if (mMap == null) {
SupportMapFragment mapFrag =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mMap = mapFrag.getMap();
}
return (mMap != null);
}
#SuppressWarnings("unused")
private void gotoLocation(double lat, double lng) {
LatLng ll = new LatLng(lat, lng);
CameraUpdate update = CameraUpdateFactory.newLatLng(ll);
mMap.moveCamera(update);
}
private void gotoLocation(double lat, double lng,
float zoom) {
LatLng ll = new LatLng(lat, lng);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, zoom);
mMap.moveCamera(update);
}
public void geoLocate(View v) throws IOException {
hideSoftKeyboard(v);
EditText et = (EditText) findViewById(R.id.editText1);
String location = et.getText().toString();
Geocoder gc = new Geocoder(this);
List<Address> list = gc.getFromLocationName(location, 1);
Address add = list.get(0);
String locality = add.getLocality();
Toast.makeText(this, locality, Toast.LENGTH_LONG).show();
double lat = add.getLatitude();
double lng = add.getLongitude();
gotoLocation(lat, lng, DEFAULTZOOM);
}
private void hideSoftKeyboard(View v) {
InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.mapTypeNone:
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
break;
case R.id.mapTypeNormal:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
break;
case R.id.mapTypeSatellite:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
break;
case R.id.mapTypeTerrain:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
break;
case R.id.mapTypeHybrid:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
break;
case R.id.gotoCurrentLocation:
gotoCurrentLocation();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onStop() {
super.onStop();
MapStateManager mgr = new MapStateManager(this);
mgr.saveMapState(mMap);
}
#Override
protected void onResume() {
super.onResume();
MapStateManager mgr = new MapStateManager(this);
CameraPosition position = mgr.getSavedCameraPosition();
if (position != null) {
CameraUpdate update = CameraUpdateFactory.newCameraPosition(position);
mMap.moveCamera(update);
// This is part of the answer to the code challenge
mMap.setMapType(mgr.getSavedMapType());
}
}
protected void gotoCurrentLocation() {
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnected(Bundle arg0) {
Toast.makeText(this, "Connected to location service", Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
}
The second and third parameters of constructor have a type of:
GooglePlayServicesClient.ConnectionCallbacks
GooglePlayServicesClient.OnConnectionFailedListener
So you should implement these interfaces in your Activity, if you are pointing to this. But you've picked up similar interfaces from another class - GoogleApiClient
Not familiar with android apis but looks like a bad import of ConnectionCallbacks (import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;). When you cast to ConnectionCallbacks its using that bad import instead of GoogleApiClient.ConnectionCallbacks.
Edited:
ok so its the other way around!
I'm still in the process of learning java, so I'm sorry if this question is too obvious. I'm trying to launch my app and it throws this error. The problem seems to be in the OnCreate() method, but I can't figure out what's causing it.
import java.util.Calendar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;
public class MainActivity extends Activity {
public final static String NAME = "nick.miros.famous.problems.MESSAGE";
public final static String EMAIL = "nick.miros.famous.problems.MESSAGE1";
public final static String STUFFSEX = "nick.miros.famous.problems.MESSAGE2";
public final static String BIRTHDAY = "nick.miros.famous.problems.MESSAGE3";
private boolean agreed;
private String sex;
public static String bornDate;
public EditText emailEdit;
public EditText nameEdit;
public EditText passwordEdit;
// public EditText passwordRepeatEdit;
public RadioGroup radioSex;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nameEdit = (EditText) findViewById(R.id.name);
emailEdit = (EditText) findViewById(R.id.email);
passwordEdit = (EditText) findViewById(R.id.password);
// passwordRepeatEdit = (EditText) findViewById(R.id.passwordRepeat);
emailEdit.addTextChangedListener(new GenericTextWatcher(emailEdit));
nameEdit.addTextChangedListener(new GenericTextWatcher(nameEdit));
passwordEdit
.addTextChangedListener(new GenericTextWatcher(passwordEdit));
// passwordRepeatEdit.addTextChangedListener(new
// GenericTextWatcher(passwordRepeatEdit));
Button Go = (Button) findViewById(R.id.sendButton);
Go.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
sendAndCheck();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private String getSex(int id) {
switch (id) {
case R.id.radioMale:
sex = "Male";
break;
case R.id.radioFemale:
sex = "Female";
break;
}
return sex;
}
public void showThanks() {
Toast.makeText(this.getApplicationContext(), R.string.thank_you,
Toast.LENGTH_LONG).show();
}
public void onCheckBoxClicked(View view) {
// Is the view now checked?
agreed = ((CheckBox) findViewById(R.id.agreementBox)).isChecked();
}
public final static boolean isValidEmail(CharSequence target) {
if (target == null) {
return false;
} else {
return android.util.Patterns.EMAIL_ADDRESS.matcher(target)
.matches();
}
}
public static class DatePickerFragment extends DialogFragment implements
DatePickerDialog.OnDateSetListener {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the current date as the default date in the picker
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
// Create a new instance of DatePickerDialog and return it
return new DatePickerDialog(getActivity(), this, year, month, day);
}
public void onDateSet(DatePicker view, int year, int month, int day) {
// Do something with the date chosen by the user
bornDate = Integer.toString(year) + "/" + Integer.toString(month)
+ "/" + Integer.toString(day);
}
}
public void showDatePickerDialog(View v) {
DialogFragment newFragment = new DatePickerFragment();
newFragment.show(getFragmentManager(), "datePicker");
}
/** Called when the user clicks the Send button */
public void sendAndCheck() {
CharSequence emailToCheck = ((EditText) findViewById(R.id.email))
.getText().toString();
if (agreed) {
// Do something in response to button
if (isValidEmail(emailToCheck)) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
String sent_name = ((EditText) findViewById(R.id.name))
.getText().toString();
String sent_email = ((EditText) findViewById(R.id.email))
.getText().toString();
int id = ((RadioGroup) findViewById(R.id.radioSex))
.getCheckedRadioButtonId();
String sent_sex = getSex(id);
String sent_birthday = bornDate;
intent.putExtra(NAME, sent_name);
intent.putExtra(EMAIL, sent_email);
intent.putExtra(STUFFSEX, sent_sex);
intent.putExtra(BIRTHDAY, sent_birthday);
startActivity(intent);
showThanks();
} else {
((EditText) findViewById(R.id.email)).setError("wrong email!");
}
} else {
AlertDialog.Builder Alert = new AlertDialog.Builder(this);
Alert.setMessage("Please agree with the terms and conditions first");
Alert.setTitle("Notice");
Alert.setPositiveButton("OK", null);
Alert.setCancelable(true);
Alert.create().show();
}
}
}
Here is the GenericTextWatcher:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
public class GenericTextWatcher implements TextWatcher{
private View view;
private PasswordValidator passwordValidator = new PasswordValidator();
String password = ((EditText) view).getText().toString();
GenericTextWatcher(View view) {
this.view = view;
}
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
public void afterTextChanged(Editable editable) {
String text = editable.toString();
switch(view.getId()){
case R.id.name:
if (!(text.equals("")))
{
}
else
{
((EditText) view).setError("wrong name!");
}
break;
case R.id.email:
CharSequence emailToCheck = ((EditText) view).getText().toString();
if (isValidEmail(emailToCheck))
{
}
else
{
((EditText) view).setError("wrong email!");
}
break;
case R.id.password:
if (passwordValidator.isValidPassword(text))
{
}
else
{
((EditText) view).setError("must have 1 uppercase letter, 1 number and be 6 characters long");
}
break;
/* case R.id.passwordRepeat:
String password = (((EditText) view) findViewById(R.id.password).getText().toString();
if (text.equals(password))
{
}
else
{
((EditText) view).setError("passwords don't match");
}
break;*/
}
}
public final static boolean isValidEmail(CharSequence target) {
if (target == null) {
return false;
} else {
return android.util.Patterns.EMAIL_ADDRESS.matcher(target)
.matches();
}
}
public class PasswordValidator{
private Pattern pattern;
private Matcher matcher;
private static final String PASSWORD_PATTERN =
"((?=.*\\d)(?=.*[A-Z]).{6,20})";
public PasswordValidator(){
pattern = Pattern.compile(PASSWORD_PATTERN);
}
/**
* Validate password with regular expression
* #param password password for validation
* #return true valid password, false invalid password
*/
public boolean isValidPassword(String password){
matcher = pattern.matcher(password);
return matcher.matches();
}
}
}
Here is the LogCat:
02-04 03:59:14.267: D/dalvikvm(2400): GC_FOR_ALLOC freed 37K, 7% free 2640K/2820K, paused 1ms, total 34ms
02-04 03:59:14.267: I/dalvikvm-heap(2400): Grow heap (frag case) to 3.319MB for 635808-byte allocation
02-04 03:59:14.277: D/dalvikvm(2400): GC_FOR_ALLOC freed 2K, 6% free 3258K/3444K, paused 10ms, total 10ms
02-04 03:59:14.377: D/AndroidRuntime(2400): Shutting down VM
02-04 03:59:14.377: W/dalvikvm(2400): threadid=1: thread exiting with uncaught exception (group=0xb2eb7648)
02-04 03:59:14.377: E/AndroidRuntime(2400): FATAL EXCEPTION: main
02-04 03:59:14.377: E/AndroidRuntime(2400): java.lang.RuntimeException: Unable to start activity ComponentInfo{nick.miros.famous.problems/nick.miros.famous.problems.MainActivity}: java.lang.NullPointerException
02-04 03:59:14.377: E/AndroidRuntime(2400): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
02-04 03:59:14.377: E/AndroidRuntime(2400): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
02-04 03:59:14.377: E/AndroidRuntime(2400): at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-04 03:59:14.377: E/AndroidRuntime(2400): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
02-04 03:59:14.377: E/AndroidRuntime(2400): at android.os.Handler.dispatchMessage(Handler.java:99)
02-04 03:59:14.377: E/AndroidRuntime(2400): at android.os.Looper.loop(Looper.java:137)
02-04 03:59:14.377: E/AndroidRuntime(2400): at android.app.ActivityThread.main(ActivityThread.java:5103)
02-04 03:59:14.377: E/AndroidRuntime(2400): at java.lang.reflect.Method.invokeNative(Native Method)
02-04 03:59:14.377: E/AndroidRuntime(2400): at java.lang.reflect.Method.invoke(Method.java:525)
02-04 03:59:14.377: E/AndroidRuntime(2400): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
02-04 03:59:14.377: E/AndroidRuntime(2400): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-04 03:59:14.377: E/AndroidRuntime(2400): at dalvik.system.NativeStart.main(Native Method)
02-04 03:59:14.377: E/AndroidRuntime(2400): Caused by: java.lang.NullPointerException
02-04 03:59:14.377: E/AndroidRuntime(2400): at nick.miros.famous.problems.GenericTextWatcher.<init>(GenericTextWatcher.java:15)
02-04 03:59:14.377: E/AndroidRuntime(2400): at nick.miros.famous.problems.MainActivity.onCreate(MainActivity.java:46)
02-04 03:59:14.377: E/AndroidRuntime(2400): at android.app.Activity.performCreate(Activity.java:5133)
02-04 03:59:14.377: E/AndroidRuntime(2400): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
02-04 03:59:14.377: E/AndroidRuntime(2400): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
02-04 03:59:14.377: E/AndroidRuntime(2400): ... 11 more
There's a NullPointerException in GenericTextWatcher initialization (<init>), on line 15.
In there you have a member variable:
String password = ((EditText) view).getText().toString();
view is null at this point, you only assign it in constructor later. Move this code to constructor or later.
I wrote Android QuizApp which randomly generates questions for users and then displays the result. When I tried to implement user interface where a user would enter the number and difficulty of questions, application started to crash and give me fatal exceptions. I have 4 classes:
package com.example.quizapp;
import java.util.Random;
public class Quiz {
private int difficulty;
private int numberOfQuestions;
private Question[] questions;
public Quiz(String difficulty, int numberOfQuestions) {
setDifficulty(difficulty);
this.numberOfQuestions = numberOfQuestions;
this.questions = new Question[this.numberOfQuestions];
for (int i = 0; i < this.numberOfQuestions; i++) {
this.questions[i] = new Question(this.difficulty);
}
}
public void setDifficulty(String difficulty) {
if (difficulty == "easy") {
this.difficulty = 1;
} else if (difficulty == "medium"){
this.difficulty = 2;
} else if (difficulty == "hard"){
this.difficulty = 3;
} else {
this.difficulty = -1;
}
}
public String getDifficulty() {
switch (difficulty) {
case 1:
return "easy";
case 2:
return "medium";
case 3:
return "hard";
default:
return "Difficulty not set correctly";
}
}
public Question getQuestionInstance(int number) {
return this.questions[number];
}
public String getQuestion(int number) {
return this.questions[number].QUESTION;
}
public int getOptionA(int number) {
return this.questions[number].OPTA;
}
public int getOptionB(int number) {
return this.questions[number].OPTB;
}
public int getOptionC(int number) {
return this.questions[number].OPTC;
}
public int getAnswer(int number) {
return this.questions[number].ANSWER;
}
class Question {
private int firstNumber;
private int secondNumber;
private char sign;
private String QUESTION;
private int OPTA;
private int OPTB;
private int OPTC;
private int ANSWER;
private int difficulty;
private Random rand;
public Question(int difficulty) {
this.difficulty = difficulty;
this.rand = new Random();
this.firstNumber = getRandomNumber();
this.secondNumber = getRandomNumber();
this.sign = getRandomSign();
this.ANSWER = calculateAnswer();
initializeOptions();
this.QUESTION = this.firstNumber + " " + this.sign + " " + this.secondNumber + " = ";
}
public String getQuestion() {
return this.QUESTION;
}
public int getOptionA() {
return this.OPTA;
}
public int getOptionB() {
return this.OPTB;
}
public int getOptionC() {
return this.OPTC;
}
public int getAnswer() {
return this.ANSWER;
}
private void initializeOptions() {
int number = this.rand.nextInt(3) + 1;
switch (number) {
case 1:
this.OPTA = this.ANSWER;
this.OPTB = (int) Math.floor(this.ANSWER - this.ANSWER / 100.0 * (this.rand.nextInt(81) + 20));
this.OPTC = (int) Math.floor(this.ANSWER + this.ANSWER / 100.0 * (this.rand.nextInt(81) + 20));
break;
case 2:
this.OPTA = (int) Math.floor(this.ANSWER - this.ANSWER / 100.0 * (this.rand.nextInt(81) + 20));
this.OPTB = this.ANSWER;
this.OPTC = (int) Math.floor(this.ANSWER + this.ANSWER / 100.0 * (this.rand.nextInt(81) + 20));
break;
case 3:
this.OPTA = (int) Math.floor(this.ANSWER - this.ANSWER / 100.0 * (this.rand.nextInt(81) + 20));
this.OPTB = (int) Math.floor(this.ANSWER + this.ANSWER / 100.0 * (this.rand.nextInt(81) + 20));
this.OPTC = this.ANSWER;
break;
}
}
private int calculateAnswer() {
int answer = 0;
switch (this.sign) {
case '+':
answer = this.firstNumber + this.secondNumber;
break;
case '-':
answer = this.firstNumber - this.secondNumber;
break;
case '*':
answer = this.firstNumber * this.secondNumber;
break;
case '/':
answer = this.firstNumber / this.secondNumber;
break;
}
return answer;
}
private int getRandomNumber() {
int number;
if (this.difficulty == 1) {
//number = 1 + Math.random()*100;
number = this.rand.nextInt(100) + 1;
} else if (this.difficulty == 2) {
//number = 1 + Math.random()*1000;
number = this.rand.nextInt(1000) + 1;
} else {
//number = 1 + Math.random()*1000;
number = this.rand.nextInt(1000) + 1;
}
return number;
}
private char getRandomSign() {
int number;
char sign;
//easy
if (this.difficulty == 1) {
number = this.rand.nextInt(2) + 1;
sign = convertNumberToSign(number);
//medium
} else if (this.difficulty == 2) {
if (this.firstNumber > 10 && this.secondNumber > 10) {
number = this.rand.nextInt(2) + 1;
sign = convertNumberToSign(number);
} else {
number = this.rand.nextInt(3) + 1;
sign = convertNumberToSign(number);
}
//hard
} else {
if (this.firstNumber / this.secondNumber == (int) (this.firstNumber / this.secondNumber)) {
number = this.rand.nextInt(4) + 1;
sign = convertNumberToSign(number);
} else {
number = this.rand.nextInt(3) + 1;
sign = convertNumberToSign(number);
}
}
return sign;
}
private char convertNumberToSign(int number) {
if (number == 1) {
return '+';
} else if (number == 2) {
return '-';
} else if (number == 3) {
return '*';
} else {
return '/';
}
}
}
}
package com.example.quizapp;
import com.example.quizapp.R;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
public class QuizActivity extends Activity
{
Quiz quiz;
RadioButton rb1, rb2, rb3, rb4, rb5, rb6;
Button buttonOK;
String ans;
int num = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ui);
rb1=(RadioButton)findViewById(R.id.radio3);
rb2=(RadioButton)findViewById(R.id.radio4);
rb3=(RadioButton)findViewById(R.id.radio5);
rb4=(RadioButton)findViewById(R.id.radio6);
rb5=(RadioButton)findViewById(R.id.radio7);
rb6=(RadioButton)findViewById(R.id.radio8);
buttonOK=(Button)findViewById(R.id.button2);
buttonOK.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RadioGroup group2=(RadioGroup)findViewById(R.id.radioGroup3);
RadioButton answer2=(RadioButton)findViewById(group2.getCheckedRadioButtonId());
if (answer2.equals(rb4))
{
num = 5;
}
else if (answer2.equals(rb5))
{
num = 10;
}
else
{
num = 15;
}
RadioGroup group1=(RadioGroup)findViewById(R.id.radioGroup2);
RadioButton answer1=(RadioButton)findViewById(group1.getCheckedRadioButtonId());
if (answer1.equals(rb1))
{
ans = "easy";
}
else if (answer1.equals(rb2))
{
ans = "medium";
}
else
{
ans = "hard";
}
}
});
Intent intent = new Intent(QuizActivity.this, QuestActivity.class);
intent.putExtra("answer", ans);
intent.putExtra("question", num);
QuizActivity.this.startActivity(intent);
finish();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_ui, menu);
return true;
}
}
package com.example.quizapp;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
public class QuestActivity extends Activity
{
Quiz quiz;
int score = 0;
int qid = 0;
Quiz.Question currentQuest;
TextView textQuestion;
RadioButton rba, rbb, rbc;
Button buttonNext;
String answer = null;
int numOfQuestion = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
Intent intent= getIntent();
if (intent != null)
{
answer=intent.getStringExtra("answer");
numOfQuestion=intent.getIntExtra("question", 0);
}
quiz= new Quiz(answer,numOfQuestion);
currentQuest=quiz.getQuestionInstance(qid);
textQuestion=(TextView)findViewById(R.id.textView1);
rba=(RadioButton)findViewById(R.id.radio0);
rbb=(RadioButton)findViewById(R.id.radio1);
rbc=(RadioButton)findViewById(R.id.radio2);
buttonNext=(Button)findViewById(R.id.button1);
setQuestionView();
buttonNext.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
RadioGroup group=(RadioGroup)findViewById(R.id.radioGroup1);
RadioButton answer=(RadioButton)findViewById(group.getCheckedRadioButtonId());
Log.d("yourans", currentQuest.getAnswer() + " " + answer.getText());
if(Integer.toString(currentQuest.getAnswer()).equals(answer.getText()) )
{
score++;
Log.d("score", "Your score" + score);
}
if(qid<numOfQuestion)
{
currentQuest=quiz.getQuestionInstance(qid);
setQuestionView();
}else
{
Intent intent = new Intent(QuestActivity.this, ResultActivity.class);
Bundle b = new Bundle();
b.putInt("score", score);
intent.putExtras(b);
startActivity(intent);
finish();
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_quiz, menu);
return true;
}
private void setQuestionView()
{
textQuestion.setText(currentQuest.getQuestion());
rba.setText(Integer.toString(currentQuest.getOptionA()));
rbb.setText(Integer.toString(currentQuest.getOptionB()));
rbc.setText(Integer.toString(currentQuest.getOptionC()));
qid++;
}
}
package com.example.quizapp;
import com.example.quizapp.R;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.RatingBar;
import android.widget.TextView;
public class ResultActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
//access rating bar
RatingBar rbar=(RatingBar)findViewById(R.id.ratingBar1);
rbar.setNumStars(5);
rbar.setStepSize(0.5f);
TextView t=(TextView)findViewById(R.id.textResult);
//get and display the score
Bundle b = getIntent().getExtras();
int score= b.getInt("score");
rbar.setRating(score);
switch (score)
{
case 1:
case 2: t.setText("Better Luck Next Time!");
break;
case 3:
case 4:t.setText("Quite average");
break;
case 5:t.setText("Congratulations !");
break;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.activity_result, menu);
return true;
}
}
Edited: I added AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.quizapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.quizapp.QuizActivity"
android:label="#string/quiz_app" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.quizapp.QuestActivity"
android:label="#string/title_activity_quiz" >
</activity>
<activity
android:name="com.example.quizapp.ResultActivity"
android:label="#string/title_activity_result" >
</activity>
</application>
</manifest>
Edited: Updated application as suggested, this error pops up and app crashes:
10-23 10:10:32.368: E/AndroidRuntime(827): FATAL EXCEPTION: main
10-23 10:10:32.368: E/AndroidRuntime(827): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.quizapp/com.example.quizapp.QuestActivity}: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
10-23 10:10:32.368: E/AndroidRuntime(827): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
10-23 10:10:32.368: E/AndroidRuntime(827): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
10-23 10:10:32.368: E/AndroidRuntime(827): at android.app.ActivityThread.access$600(ActivityThread.java:141)
10-23 10:10:32.368: E/AndroidRuntime(827): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
10-23 10:10:32.368: E/AndroidRuntime(827): at android.os.Handler.dispatchMessage(Handler.java:99)
10-23 10:10:32.368: E/AndroidRuntime(827): at android.os.Looper.loop(Looper.java:137)
10-23 10:10:32.368: E/AndroidRuntime(827): at android.app.ActivityThread.main(ActivityThread.java:5103)
10-23 10:10:32.368: E/AndroidRuntime(827): at java.lang.reflect.Method.invokeNative(Native Method)
10-23 10:10:32.368: E/AndroidRuntime(827): at java.lang.reflect.Method.invoke(Method.java:525)
10-23 10:10:32.368: E/AndroidRuntime(827): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
10-23 10:10:32.368: E/AndroidRuntime(827): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-23 10:10:32.368: E/AndroidRuntime(827): at dalvik.system.NativeStart.main(Native Method)
10-23 10:10:32.368: E/AndroidRuntime(827): Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
10-23 10:10:32.368: E/AndroidRuntime(827): at com.example.quizapp.Quiz.getQuestionInstance(Quiz.java:45)
10-23 10:10:32.368: E/AndroidRuntime(827): at com.example.quizapp.QuestActivity.onCreate(QuestActivity.java:52)
10-23 10:10:32.368: E/AndroidRuntime(827): at android.app.Activity.performCreate(Activity.java:5133)
10-23 10:10:32.368: E/AndroidRuntime(827): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
10-23 10:10:32.368: E/AndroidRuntime(827): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
10-23 10:10:32.368: E/AndroidRuntime(827): ... 11 more
check this in manifest:
android:name="com.example.quizapp.QuizApp"
Have you this activity "QuizApp"?
change in manifest to:
android:name="com.example.quizapp.QuizActivity"
HTH.
You told Android that you have an Activity named QuizApp as your Main Activity, by saying
<activity
android:name="com.example.quizapp.QuizApp"
android:label="#string/quiz_app" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
but you never implemented it. Android looks for that activity in the package, com.example.quizapp, but it fails to find it, as we can see from the ClassNotFoundException in the LogCat messages,
10-21 06:31:26.907: E/AndroidRuntime(816): ... java.lang.ClassNotFoundException: Didn't find class "com.example.quizapp.QuizApp"...
You must implement your QuizApp Activity.
Its look like you have package name mismatch error in Manifest file. Correct it as
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.quizapp"
...
</manifest>
And don't forget, you can specify the fully qualified name for each Activity
i.e.
<activity
android:name="com.example.quizapp.Activity_name"
...>
</activity>
Edit As per Requirement
package com.example.quizapp;
import com.example.quizapp.R;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
public class QuizActivity extends Activity
{
Quiz quiz;
RadioButton rb1, rb2, rb3, rb4, rb5, rb6;
Button buttonOK;
String ans;
int num = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ui);
rb1=(RadioButton)findViewById(R.id.radio3);
rb2=(RadioButton)findViewById(R.id.radio4);
rb3=(RadioButton)findViewById(R.id.radio5);
rb4=(RadioButton)findViewById(R.id.radio6);
rb5=(RadioButton)findViewById(R.id.radio7);
rb6=(RadioButton)findViewById(R.id.radio8);
buttonOK=(Button)findViewById(R.id.button2);
buttonOK.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RadioGroup group2=(RadioGroup)findViewById(R.id.radioGroup3);
RadioButton answer2=(RadioButton)findViewById(group2.getCheckedRadioButtonId());
if (answer2.equals(rb4))
{
num = 5;
}
else if (answer2.equals(rb5))
{
num = 10;
}
else
{
num = 15;
}
RadioGroup group1=(RadioGroup)findViewById(R.id.radioGroup2);
RadioButton answer1=(RadioButton)findViewById(group1.getCheckedRadioButtonId());
if (answer1.equals(rb1))
{
ans = "easy";
}
else if (answer1.equals(rb2))
{
ans = "medium";
}
else
{
ans = "hard";
}
}
});
//*********Edit
//Intent intent = new Intent(QuizActivity.this, QuestActivity.class);
//QuizActivity.this.startActivity(intent);
//finish();
Intent intent = new Intent(QuizActivity.this, QuestActivity.class);
intent.putExtra("answer", ans);
intent.putExtra("question", num);
QuizActivity.this.startActivity(intent);
finish();
//*******Edit
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_ui, menu);
return true;
}
}
Here Next Activity
package com.example.quizapp;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
public class QuestActivity extends Activity
{
Quiz quiz;
int score = 0;
int qid = 0;
Quiz.Question currentQuest;
TextView textQuestion;
RadioButton rba, rbb, rbc;
Button buttonNext;
QuizActivity qa = new QuizActivity();
String ans = qa.ans;
int num = qa.num;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
//*********Edit
Intent intent= getActivity().getIntent();
String answer=intent.getStringExtra("answer");
int numOfQuestion=intent.getIntExtra("question", 0);
//quiz= new Quiz(ans, num);
quiz= new Quiz(answer,numOfQuestion);
//*******
currentQuest=quiz.getQuestionInstance(qid);
textQuestion=(TextView)findViewById(R.id.textView1);
rba=(RadioButton)findViewById(R.id.radio0);
rbb=(RadioButton)findViewById(R.id.radio1);
rbc=(RadioButton)findViewById(R.id.radio2);
buttonNext=(Button)findViewById(R.id.button1);
setQuestionView();
buttonNext.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
RadioGroup group=(RadioGroup)findViewById(R.id.radioGroup1);
RadioButton answer=(RadioButton)findViewById(group.getCheckedRadioButtonId());
Log.d("yourans", currentQuest.getAnswer() + " " + answer.getText());
if(Integer.toString(currentQuest.getAnswer()).equals(answer.getText()) )
{
score++;
Log.d("score", "Your score" + score);
}
if(qid<num)
{
currentQuest=quiz.getQuestionInstance(qid);
setQuestionView();
}else
{
Intent intent = new Intent(QuestActivity.this, ResultActivity.class);
Bundle b = new Bundle();
b.putInt("score", score);
intent.putExtras(b);
startActivity(intent);
finish();
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_quiz, menu);
return true;
}
private void setQuestionView()
{
textQuestion.setText(currentQuest.getQuestion());
rba.setText(Integer.toString(currentQuest.getOptionA()));
rbb.setText(Integer.toString(currentQuest.getOptionB()));
rbc.setText(Integer.toString(currentQuest.getOptionC()));
qid++;
}
}
I'm trying to receive array in proximity alert. The only thing I could send is one Long. This is how I set proximity alert:
private void setProximityAlert(double lat, double lon, final long eventID, int requestCode)
{
float radius = 30f;
LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Intent intent = new Intent(PROXIMITY_INTENT_ACTION);
intent.putExtra(ProximityAlert.EVENT_ID_INTENT_EXTRA, eventID);
intent.putExtra("pole", mPositions);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);
locManager.addProximityAlert(lat, lon, radius, -1, pendingIntent);
}
It doesn't crash when i comment "intent.putExtra("pole", mPositions);".
This is the array:
private ArrayList<LatLonPair> mPositions;
And this is receiver:
public class ProximityAlert extends BroadcastReceiver {
public static final String EVENT_ID_INTENT_EXTRA = "EventIDIntentExtraKey";
#Override
public void onReceive(Context context, Intent intent) {
long eventID = intent.getLongExtra(EVENT_ID_INTENT_EXTRA, -1);
ArrayList<LatLonPair> list = (ArrayList<LatLonPair>) intent.getSerializableExtra("list");
Toast.makeText(context, "Event: " + eventID, Toast.LENGTH_SHORT).show();
}
}
Without the one putExtra it's working, but i need that array. So this is not working for me:
Array List of objects via intent
LogCat error:
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{co.uk.gauntface.android.proximityalerts/co.uk.gauntface.android.proximityalerts.ProximityDisplay}: java.lang.RuntimeException: Parcel: unable to marshal value co.uk.gauntface.android.proximityalerts.models.LatLonPair#44fb61f0
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
at android.app.ActivityThread.access$2300(ActivityThread.java:125)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Parcel: unable to marshal value co.uk.gauntface.android.proximityalerts.models.LatLonPair#44fb61f0
at android.os.Parcel.writeValue(Parcel.java:1116)
at android.os.Parcel.writeList(Parcel.java:510)
at android.os.Parcel.writeValue(Parcel.java:1076)
at android.os.Parcel.writeMapInternal(Parcel.java:479)
at android.os.Bundle.writeToParcel(Bundle.java:1552)
at android.os.Parcel.writeBundle(Parcel.java:493)
at android.content.Intent.writeToParcel(Intent.java:5438)
at android.app.ActivityManagerProxy.getIntentSender(ActivityManagerNative.java:2206)
at android.app.PendingIntent.getBroadcast(PendingIntent.java:230)
at co.uk.gauntface.android.proximityalerts.ProximityDisplay.setProximityAlert(ProximityDisplay.java:91)
at co.uk.gauntface.android.proximityalerts.ProximityDisplay.registerIntents(ProximityDisplay.java:79)
at co.uk.gauntface.android.proximityalerts.ProximityDisplay.onCreate(ProximityDisplay.java:43)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
... 11 more
This is LatLonPair Class:
package co.uk.gauntface.android.proximityalerts.models;
import android.os.Parcel;
import android.os.Parcelable;
import com.google.android.maps.GeoPoint;
public class LatLonPair implements Parcelable{
private double mLatitude;
private double mLongitude;
private String popis;
private String nadpis;
public LatLonPair() {
mLatitude = -2.60312596534349;
mLongitude = 51.4558140934651;
popis = "Nezadany popis";
nadpis = "Nezadany nadpis";
}
public LatLonPair(double latitude, double longitude, String popis, String nadpis) {
mLatitude = latitude;
mLongitude = longitude;
this.popis = popis;
this.nadpis = nadpis;
}
public static boolean isValid(double lat, double lon) {
if((lon >= -180 && lon <= 180) && (lat >= -90 && lat <= 90)) {
return true;
}
return false;
}
public String getPopis() {
return popis;
}
public String getNadpis() {
return nadpis;
}
public void setLatitude(double latitude) {
mLatitude = latitude;
}
public double getLatitude() {
return mLatitude;
}
public void setLongitude(double longitude) {
mLongitude = longitude;
}
public double getLongitude() {
return mLongitude;
}
public GeoPoint getGeoPoint() {
return new GeoPoint((int) (mLatitude * 1E6), (int) (mLongitude * 1E6));
}
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
}
}
Try calling super(dest,flags) in the overridden writeToParcel method in LatLonPair class
Problem was I didn't have implements Parceable and after that it didn't have CREATE. After that it wasn't crashing and the array lenght was OK, but items had default value. I guess problem was with bad implementation of saving variables in Parceable - it reseted itself. So I gave up and send to broadcastreceiver just few strings I needed there. Thank you all for help.