I implemented AsyncTask to execute results. Here is the error I get...
FATAL EXCEPTION: AsyncTask #1
Process: ai69.psoui, PID: 3287
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.app.Activity.<init>(Activity.java:754)
at android.support.v4.app.SupportActivity.<init>(SupportActivity.java:31)
at android.support.v4.app.BaseFragmentActivityGingerbread.<init>(BaseFragmentActivityGingerbread.java:37)
at android.support.v4.app.BaseFragmentActivityHoneycomb.<init>(BaseFragmentActivityHoneycomb.java:29)
at android.support.v4.app.BaseFragmentActivityJB.<init>(BaseFragmentActivityJB.java:30)
at android.support.v4.app.FragmentActivity.<init>(FragmentActivity.java:79)
at android.support.v7.app.AppCompatActivity.<init>(AppCompatActivity.java:61)
at ai69.psoui.MainActivity.<init>(MainActivity.java:0)
at android_tests.CustomUseCase.<init>(CustomUseCase.java:19)
at android_tests.TestFactory.getTest(TestFactory.java:15)
at ai69.psoui.ParticleActivity.runTest(ParticleActivity.java:91)
at ai69.psoui.ParticleActivity$runTests.doInBackground(ParticleActivity.java:53)
at ai69.psoui.ParticleActivity$runTests.doInBackground(ParticleActivity.java:50)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
I have looked at different SOF posts about "Looper.prepare()" but the thing is, prior to a few changes in changing static variables to getter/setter methods, my UI was working fine.
Here is my code...
public class ParticleActivity extends AppCompatActivity {
public final static String EXTRA_MESSAGE = "PSOUI.MESSAGE";
private ProgressDialog pd;
private double[] results = {-1.0, -1.0, -1.0};
EditText particles;
EditText iterations;
EditText userSol;
EditText userBatt;
private double battery;
private double solution;
//int numberOfDimensions = MainActivity.dimensions.size();
//public ArrayList<Double> costData = MainActivity.costDATA; //costs that
the user enters for each resource
//public ArrayList<Double> costWlan = MainActivity.costWLAN;
//public ArrayList<Double> costUtilities = MainActivity.costUTILITY;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_particle);
particles = (EditText) findViewById(R.id.particles);
iterations = (EditText) findViewById(R.id.iterations);
userSol = (EditText) findViewById(R.id.solution);
userBatt = (EditText) findViewById(R.id.battery);
pd = null;
runPSOButton();
}
#Override
public void onPause(){
super.onPause();
if(pd != null)
pd.dismiss();
}
public class runTests extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) { //sort this out
results = runTest("CustomUseCase"); //i only want to run this one!!!
return null;
}
#Override
protected void onPostExecute(Void v) {
if (results != null && results.length > 0 && results[0] != -1) {
loadIntent(results);
} //otherwise it will evaluate the next logic statement results[0] != -1 with no chance of NulLPointerException
}
#Override
protected void onPreExecute() {
pd = ProgressDialog.show(ParticleActivity.this, "Busy", "Algorithm is currently executing");
pd.setCancelable(true);
pd.show();
}
}
public void runPSOButton() {
final Button runPSO = (Button) findViewById(R.id.runpso);
runPSO.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
new runTests().execute();
}
});
}
public double[] runTest(String test) {
int noPart = Integer.parseInt(particles.getText().toString());
int noIter = Integer.parseInt(iterations.getText().toString());
return new TestFactory(noPart, noIter).getTest(test).test();
}
public void loadIntent(double[] result) {
double[] results = result;
Intent intent = new Intent(this, SolutionActivity.class);
intent.putExtra(EXTRA_MESSAGE, results);
startActivity(intent);
}
public double setBatteryCost(){
battery = Double.parseDouble(userBatt.getText().toString());
return battery;
}
public double getBatteryCost(){return setBatteryCost();}
public double setUserSolution(){
solution = Double.parseDouble(userSol.getText().toString());
return solution;
}
public double getUserSolution(){return setUserSolution();}
}
Can someone explain whats happening? New to Android Studio and have been developing for only 3 months in Java, so for any solutions can I kindly request an explanation for it too? Much appreciated thank you
UPDATE:
Here is my mainActivity...
public class MainActivity extends AppCompatActivity {
//declare variables
EditText name;
EditText data;
EditText wlan;
EditText utility;
Button addservice;
ListView lv;
ListView lv2;
ListView lv3;
ListView lv4;
public ArrayList<String> servicenames;
public ArrayList<String> dimensions;
public ArrayList<Double> costDATA;
public ArrayList<Double> costWLAN;
public ArrayList<Double> costUTILITY;
ArrayAdapter<String> namesAdapter;
ArrayAdapter<Double> dataAdapter;
ArrayAdapter<Double> wlanAdapter;
ArrayAdapter<Double> utilityAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//map the components to the variables
name = (EditText) findViewById(R.id.servicename);
data = (EditText) findViewById(R.id.data);
wlan = (EditText) findViewById(R.id.wlan);
utility = (EditText) findViewById(R.id.utility);
addservice = (Button) findViewById(R.id.addservice);
lv = (ListView) findViewById(R.id.lv);
lv2 = (ListView) findViewById(R.id.lv2);
lv3 = (ListView) findViewById(R.id.lv3);
lv4 = (ListView) findViewById(R.id.lv4);
//create arraylists for each component
servicenames = new ArrayList<String>();
dimensions = new ArrayList<String>();
costDATA = new ArrayList<Double>();
costWLAN = new ArrayList<Double>();
costUTILITY = new ArrayList<Double>();
//create adapters to pass on the arraylist
namesAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, servicenames);
dataAdapter = new ArrayAdapter<Double>(MainActivity.this, android.R.layout.simple_list_item_1, costDATA);
wlanAdapter = new ArrayAdapter<Double>(MainActivity.this, android.R.layout.simple_list_item_1, costWLAN);
utilityAdapter = new ArrayAdapter<Double>(MainActivity.this, android.R.layout.simple_list_item_1, costUTILITY);
//display each arraylist in the listviews
lv.setAdapter(namesAdapter);
lv2.setAdapter(wlanAdapter);
lv3.setAdapter(dataAdapter);
lv4.setAdapter(utilityAdapter);
namesAdapter.notifyDataSetChanged();
dataAdapter.notifyDataSetChanged();
wlanAdapter.notifyDataSetChanged();
utilityAdapter.notifyDataSetChanged();
dimensions.add("DATA");
dimensions.add("WLAN");
onClickBtn();
}
public void onClickBtn() { //when user clicks button, the user input is added to the listview, and cleared for the next service
addservice.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String namesOfService = name.getText().toString(); //user input for service names
String costOfData = data.getText().toString(); //user input for data costs
String costOfWLAN = wlan.getText().toString(); //user input for wlan costs
String costOfUtility = utility.getText().toString(); //user input for utility costs
Double doubleWLAN = Double.parseDouble(costOfWLAN); //convert user input into double
Double doubleData = Double.parseDouble(costOfData);
Double doubleUtility = Double.parseDouble(costOfUtility);
costDATA.add(doubleData); //add the double costs to each resource arraylist
costWLAN.add(doubleWLAN);
costUTILITY.add(doubleUtility);
servicenames.add(namesOfService);
dimensions.add(namesOfService);
namesAdapter.notifyDataSetChanged();
dataAdapter.notifyDataSetChanged();
wlanAdapter.notifyDataSetChanged();
utilityAdapter.notifyDataSetChanged();
name.setText(""); //empty the edit text fields when button is clicked
wlan.setText("");
data.setText("");
utility.setText("");
}
});
}
public void nextButton(View view) //next button, onto the next activity
{
Intent intent = new Intent(MainActivity.this, ParticleActivity.class);
startActivity(intent);
}
public int getDimensions(){ return dimensions.size();}
public ArrayList<String> getElements(){ return servicenames;}
public ArrayList<Double> getCostDATA(){;return costDATA;}
public ArrayList<Double> getCostWLAN(){return costUTILITY;}
public ArrayList<Double> getCostUTILITY(){return costUTILITY;}
}
As you can see, the arraylists that store the user input is accessible using getters and setters rather than setting the arraylists static (which I did before). I access these arraylists in another class called CustomUseCase and CustomService. Here is the code for customUseCase:
public class CustomUseCase extends Test {
MainActivity mainActivity = new MainActivity();
ParticleActivity particleActivity = new ParticleActivity();
private int numberOfDimensions = mainActivity.getDimensions();
private ArrayList<Double> costData = mainActivity.getCostDATA(); //costs that the user enters for each resource
private ArrayList<Double> costWlan = mainActivity.getCostWLAN();
private ArrayList<Double> costUtilities = mainActivity.getCostUTILITY();
private double batteryCost = particleActivity.getBatteryCost();
private int maxIter;
private int noParticles;
public CustomUseCase(int noParticles, int maxIterations) {
this.noParticles = noParticles;
this.maxIter = maxIterations;
}
#Override
public double[] test() {
long max = 10000; //maximum number of iterations, override //2 bits for the WLAN/DATA and the rest for the amount of services the user inputs
double[] results = new double[numberOfDimensions]; //new array of results with numOfBits as number of elements
for (int i = 1; i <= max; i++) {
BinaryPso bpso = new BinaryPso(noParticles,
numberOfDimensions);
ParticleActivity getUserInput = new ParticleActivity();
CustomService customService =
new CustomService(batteryCost, costData, costWlan, costUtilities);
long start = System.currentTimeMillis(); //start time
bpso.setSolution(getUserInput.getUserSolution()); //changed this to user selection
bpso.optimize(maxIter, customService, true);
this.found += (bpso.getFound() ? 1 : 0);
this.iterations += bpso.getSolIterations(); //use the method in bpso to get number of iterations taken
long end = System.currentTimeMillis() - start; //end time minus start time
this.sumTimes += end; //override the time spent variable
System.out.println("P-value: " + Particle.getValue(Particle.bestGlobal()));
System.out.println("P-bitCombo: " + Arrays.toString(Particle.bestGlobal()));
System.out.println("P-goodness: " + customService.getGoodness(Particle.bestGlobal()));
}
System.out.println("Time: " + sumTimes / max);
System.out.println("Iterations: " + iterations / max);
System.out.println("Success Rate: " + found);
boolean[] bestCombo = Particle.bestGlobal();
for (Boolean b : bestCombo) {
System.out.print(b + " ");
}
System.out.println();
results[0] = sumTimes / max;
results[1] = iterations / max;
results[2] = found;
return results;
}
public static List<Boolean> getBestComboArray() { //method to get best global array
boolean[] bestCombo = Particle.bestGlobal(); //calculate best global
List<Boolean> bestCombi = new ArrayList<>(bestCombo.length);
for (int x = 0; x < bestCombo.length; x++) {
bestCombi.add(bestCombo[x]);
}
return bestCombi;
}
}
And here is my CustomService class:
public class CustomService implements Goodness {
MainActivity mainActivity = new MainActivity();
private int numOfDimensions = mainActivity.getDimensions();
private ArrayList<String> serviceNames = mainActivity.getElements();
private ArrayList<Double> costData = mainActivity.getCostDATA();
private ArrayList<Double> costWlan = mainActivity.getCostWLAN();
private ArrayList<Double> costUtilities = mainActivity.getCostUTILITY();
private double batteryCost;
public void setBatteryCost(double batteryCost) {
this.batteryCost = batteryCost;
}
public CustomService(double batteryCost, ArrayList<Double> costData, ArrayList<Double> costWlan,
ArrayList<Double> costUtilities) {
if (costUtilities == null || costUtilities.size() < 1 || costData.size() < 1 || costWlan.size() < 1) {
throw new RuntimeException("Please add atleast 1 cost to Data, WLAN and Utility");
}
this.batteryCost = batteryCost; //make sure you add battery field to UI, user enters battery level
this.costData = costData;
this.costWlan = costWlan;
this.costUtilities = costUtilities;
}
public double getGoodness(boolean[] bits) {
double utility = 0.0;
double rcost = 0.0;
ArrayList<Double> resourceCost = new ArrayList<Double>();
Collections.sort(costUtilities); //sort the costUtilities arraylist
double maxValue = Collections.max(costUtilities); //get the maximum value from the costUtilities arraylist
if(bits[0] && bits[1]){
return -500;
}
if(!bits[0] || bits[1]){
return -1000;
}
for(int x = 1; x < numOfDimensions; x++){
if(bits[x] == costUtilities.contains(maxValue)){
return -1900;
}
}
if (bits[0]) {
resourceCost = costData;
} else if (bits[1]) {
resourceCost = costWlan;
}
for (int i = 2; i <= serviceNames.size(); i++) { //if i = 2, 2<=4
if (bits[i]) {
utility += costUtilities.get(i-2);
rcost += resourceCost.get(i-2);
}
}
if (rcost < batteryCost) {
return utility;
}
return utility * 0.50;
}
}
you can not update UI items on nonUIThread.
search usage of runOnUiThread on google.
call your method in runOnUiThread().
#Override
protected Void doInBackground(Void... params) { //sort this out
runOnUiThread (new Runnable() {
public void run() {
results = runTest("CustomUseCase");
}
}
return null;
}
This explains all: "Can't create handler inside thread that has not called Looper.prepare()" and it seems your TestFactory() method creates a Handler without a Looper.
Inside a secondary Thread a Handler should be like this
....
Looper.prepare();
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// do work with received messages
}
};
Looper.loop();
....
More info : What is the purpose of Looper and how to use it?
Related
I have problem in adding data to my list.
Users have to enter the data, then show the data in a RecycleView that use a model class.
App works fine, but the data is not shown on the RecycleView.
Before everything was working good, then i added a Swipe method to delete the item from the RecycleView, and I had to connect the item data to the model class.
So, my big issue is how to add data to the list.
Thanks in advance
I think the main problem is this part of code:
private void saveInfo() {
String ingredientName = ingrName.getText().toString();
int ingQuant = Integer.valueOf(ingrQuantity.getText().toString());
list.add(new CalculatorItemModel(ingredientName,String.valueOf(ingQuant)));
Here my Model Class
public class CalculatorItemModel {
private String ingName, ingQuantity;
public CalculatorItemModel(String ingName, String ingQuantity) {
this.ingName = ingName;
this.ingQuantity = ingQuantity;
}
public String getIngName() {
return ingName;
}
public void setIngName(String ingName) {
this.ingName = ingName;
}
public String getIngQuantity() {
return ingQuantity;
}
public void setIngQuantity(String ingQuantity) {
this.ingQuantity = ingQuantity;
}
}
And here my Activity
public class CalculatorActivity extends AppCompatActivity implements CallBackItemTouch{
Button btnCclcola;
TextView cancel, doneBtn, nameTV, quantityTV, resulttry;
EditText ingrName, ingrQuantity, moltiplyN;
Dialog dialog;
RecyclerView recyclerView;
List<CalculatorItemModel> list;
ConstraintLayout constraintLayout;
private CalculatorAdapter calculatorAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculator);
nameTV = findViewById(R.id.nameTV);
quantityTV = findViewById(R.id.qunatityTV);
btnCclcola = findViewById(R.id.btn_calcola);
recyclerView = findViewById(R.id.rv_calculator);
recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
calculatorAdapter = new CalculatorAdapter(list);
recyclerView.setAdapter(calculatorAdapter);
dialog = new Dialog(this);
btnCclcola.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int total = 0;
for (int i = 0; i < list.size(); i++) {
int total2 = Integer.parseInt(quantity.get(i));
total += total2;
Toast.makeText(CalculatorActivity.this, ""+ total, Toast.LENGTH_SHORT).show();
}
}
});
}
private void saveInfo() {
String ingredientName = ingrName.getText().toString();
int ingQuant = Integer.valueOf(ingrQuantity.getText().toString());
list.add(new CalculatorItemModel(ingredientName,String.valueOf(ingQuant)));
}
Call calculatorAdapter.notifyDataSetChanged() after adding item to the list.
I am making an app which consists of an activity and a service. By pressing a button the service is started, it collects data in the background from a sensor and classifies it and outputs a string. I want to display the string in a textView. Right now I can see in the log that the variable is updated 2 times every second, but when I try and update the textView from the service class nothing is happening unless I press the button, whenever I press the button, the string is displayed in the textView.
What is the easiest solution here? I tried to make the textView static and it still can't update it. Can you make it so that the view is updated automatically every second? Can I add a listener somehow? Since I am not very experienced I would like an easy solution that does not have to be a "good" one.
Here is my code
Activity:
public class CollectorActivity extends Activity {
private enum State {
IDLE, COLLECTING, TRAINING, CLASSIFYING
};
private final String[] mLabels = { Globals.CLASS_LABEL_STANDING,
Globals.CLASS_LABEL_WALKING, Globals.CLASS_LABEL_RUNNING,
Globals.CLASS_LABEL_OTHER };
private RadioGroup radioGroup;
private final RadioButton[] radioBtns = new RadioButton[4];
private Intent mServiceIntent;
private File mFeatureFile;
public static TextView mCurrentLabel;
private State mState;
private Button btnDelete;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
radioGroup = (RadioGroup) findViewById(R.id.radioGroupLabels);
radioBtns[0] = (RadioButton) findViewById(R.id.radioStanding);
radioBtns[1] = (RadioButton) findViewById(R.id.radioWalking);
radioBtns[2] = (RadioButton) findViewById(R.id.radioRunning);
radioBtns[3] = (RadioButton) findViewById(R.id.radioOther);
btnDelete = (Button) findViewById(R.id.btnDeleteData);
mCurrentLabel = (TextView) findViewById(R.id.textView);
mState = State.IDLE;
mFeatureFile = new File(getExternalFilesDir(null),
Globals.FEATURE_FILE_NAME);
mServiceIntent = new Intent(this, SensorsService.class);
}
public void onCollectClicked(View view) {
if (mState == State.IDLE) {
mState = State.COLLECTING;
((Button) view).setText(R.string.ui_collector_button_stop_title);
btnDelete.setEnabled(false);
radioBtns[0].setEnabled(false);
radioBtns[1].setEnabled(false);
radioBtns[2].setEnabled(false);
radioBtns[3].setEnabled(false);
int acvitivtyId = radioGroup.indexOfChild(findViewById(radioGroup
.getCheckedRadioButtonId()));
String label = mLabels[acvitivtyId];
Bundle extras = new Bundle();
extras.putString(Globals.CLASS_LABEL_KEY, label);
mServiceIntent.putExtras(extras);
startService(mServiceIntent);
} else if (mState == State.COLLECTING) {
mState = State.IDLE;
((Button) view).setText(R.string.ui_collector_button_start_title);
btnDelete.setEnabled(true);
radioBtns[0].setEnabled(true);
radioBtns[1].setEnabled(true);
radioBtns[2].setEnabled(true);
radioBtns[3].setEnabled(true);
stopService(mServiceIntent);
((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancelAll();
}
}
public void onDeleteDataClicked(View view) {
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
if (mFeatureFile.exists()) {
mFeatureFile.delete();
}
Toast.makeText(getApplicationContext(),
R.string.ui_collector_toast_file_deleted,
Toast.LENGTH_SHORT).show();
}
}
#Override
public void onBackPressed() {
if (mState == State.TRAINING) {
return;
} else if (mState == State.COLLECTING || mState == State.CLASSIFYING) {
stopService(mServiceIntent);
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.cancel(Globals.NOTIFICATION_ID);
}
super.onBackPressed();
}
#Override
public void onDestroy() {
// Stop the service and the notification.
// Need to check whether the mSensorService is null or not.
if (mState == State.TRAINING) {
return;
} else if (mState == State.COLLECTING || mState == State.CLASSIFYING) {
stopService(mServiceIntent);
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.cancelAll();
}
finish();
super.onDestroy();
}
And this is the "doInBackground" method in my service class. The line "CollectorActivity.mCurrentLabel.setText(classification);" is the problem. I want this to update the textView continously.
public class OnSensorChangedTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
Instance inst = new DenseInstance(mFeatLen);
inst.setDataset(mDataset);
Instance inst2 = new DenseInstance(65);
int blockSize = 0;
FFT fft = new FFT(Globals.ACCELEROMETER_BLOCK_CAPACITY);
double[] accBlock = new double[Globals.ACCELEROMETER_BLOCK_CAPACITY];
double[] re = accBlock;
double[] im = new double[Globals.ACCELEROMETER_BLOCK_CAPACITY];
double max = Double.MIN_VALUE;
while (true) {
try {
// need to check if the AsyncTask is cancelled or not in the while loop
if (isCancelled () == true)
{
return null;
}
// Dumping buffer
accBlock[blockSize++] = mAccBuffer.take().doubleValue();
if (blockSize == Globals.ACCELEROMETER_BLOCK_CAPACITY) {
blockSize = 0;
testList = new ArrayList<Double>();
// time = System.currentTimeMillis();
max = .0;
for (double val : accBlock) {
if (max < val) {
max = val;
}
}
fft.fft(re, im);
for (int i = 0; i < re.length; i++) {
double mag = Math.sqrt(re[i] * re[i] + im[i]
* im[i]);
inst.setValue(i, mag);
testList.add(i,mag);
im[i] = .0; // Clear the field
}
// Append max after frequency component
inst.setValue(Globals.ACCELEROMETER_BLOCK_CAPACITY, max);
inst2.setValue(Globals.ACCELEROMETER_BLOCK_CAPACITY, max);
testList.add(max);
classificationIndex = WekaClassifier.classify(testList.toArray());
classification = testLabel.get((int) classificationIndex);
CollectorActivity.mCurrentLabel.setText(classification);
inst.setValue(mClassAttribute, mLabel);
mDataset.add(inst);
Log.i("new instance", mDataset.size() + "");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
In doInBackground(Void... arg0) change CollectorActivity.mCurrentLabel.setText(classification); to publishProgress(classification); then change second argument from Void to String: public class OnSensorChangedTask extends AsyncTask<Void, Srting, Void> and add onProgressUpdate().
Finally your code should looks like:
public class OnSensorChangedTask extends AsyncTask<Void, Srting, Void> {
#Override
protected Void doInBackground(Void... arg0) {
//...
publishProgress(classification);
//...
}
#Override
protected Void onProgressUpdate(String... classification) {
CollectorActivity.mCurrentLabel.setText(classification[0]);
}
I am new to app development and so far my app is working as intended but only when I launch it on my device from Android Studio. For example, I have once instance variable that I give a value of 1 in the onCreate() method. When I launch the app from android studio on to my device, it works fine and the variable has a value of 1. However, when I launch it from my device without using android studio, the variable is given a value of 0. I have also found that I will get a bunch of NullPointerExceptions on variables that I know should have a value, and once again it works when launched from Android Studio, but not when launched from the device.
Here is MainActivity
public class MainActivity extends AppCompatActivity
{
private ArrayList<String> arrayList;
private ArrayList<ListItem> itemList;
private ArrayAdapter<String> adapter;
private EditText txtInput;
private int payRoll;
private String value;
private Intent mainToPayroll;
private int hours;
private int earnings;
private ArrayList<Integer> rollList;
private ArrayList<Integer> hourList;
private ArrayList<Integer> wageList;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rollList = new ArrayList<>(0);
hourList = new ArrayList<>(0);
wageList = new ArrayList<>(0);
payRoll = 1;
Bundle bun = getIntent().getExtras();
if(bun != null)
{
rollList = bun.getIntegerArrayList("rolls");
hourList = bun.getIntegerArrayList("hours");
wageList = bun.getIntegerArrayList("wages");
payRoll = bun.getInt("roll");
}
ListView listView = (ListView) findViewById(R.id.listv);
String[] items = {};
arrayList = new ArrayList<>(Arrays.asList(items));
itemList = new ArrayList<>(0);
adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.txtitem, arrayList);
listView.setAdapter(adapter);
Button btAdd = (Button) findViewById(R.id.btadd);
mainToPayroll = new Intent(this, PayrollActivity.class);
if(rollList != null)
{
for (int i = 0; i < rollList.size(); i++) {
ListItem newItem = new ListItem(rollList.get(i), hourList.get(i), wageList.get(i));
arrayList.add(newItem.toString());
itemList.add(newItem);
adapter.notifyDataSetChanged();
}
rollList.clear();
hourList.clear();
wageList.clear();
}
btAdd.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
ListItem newItem = new ListItem(payRoll, 0, 0);
arrayList.add(newItem.toString());
itemList.add(newItem);
adapter.notifyDataSetChanged();
payRoll++;
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
value = (String)adapter.getItem(position);
ListItem item = itemList.get(position);
Bundle info = new Bundle();
info.putString("val", value);
info.putInt("hours", item.getHours());
info.putInt("wage", item.getWages());
info.putInt("pos", position);
if(itemList.size() > 0)
{
for (ListItem items : itemList)
{
rollList.add(items.getPayroll());
hourList.add(items.getHours());
wageList.add(items.getWages());
}
}
info.putIntegerArrayList("rolls", rollList);
info.putIntegerArrayList("hours", hourList);
info.putIntegerArrayList("wages", wageList);
info.putInt("roll", payRoll);
info.putBoolean("rest", restore);
mainToPayroll.putExtras(info);
startActivity(mainToPayroll);
}
});
}
This Activity is started whenever an item on the listview is clicked
public class PayrollActivity extends AppCompatActivity
{
private static TextView text;
private String payrollNumber;
private int payrollHrs;
private int payrollWages;
private int position;
private Intent payrollToMain;
private Button returnButton;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_payroll);
final Bundle info = getIntent().getExtras();
System.out.print(getIntent().getType());
payrollNumber = info.getString("val");
payrollHrs = info.getInt("hours");
payrollWages = info.getInt("wage");
position = info.getInt("pos");
payrollToMain = new Intent(this, MainActivity.class);
returnButton = (Button) findViewById(R.id.btnRtrn);
returnButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Bundle thing = new Bundle();
thing.putIntegerArrayList("rolls", info.getIntegerArrayList("rolls"));
thing.putIntegerArrayList("hours", info.getIntegerArrayList("hours"));
thing.putIntegerArrayList("wages", info.getIntegerArrayList("wages"));
thing.putInt("roll", info.getInt("roll"));
thing.putBoolean("rest", info.getBoolean("rest"));
payrollToMain.putExtras(thing);
startActivity(payrollToMain);
}
});
text = (TextView) findViewById(R.id.title);
text.setText(payrollNumber);
}
public static void setLabelText(String val)
{
text.setText(val);
}
This is a class I created for the items that go on the listview
public class ListItem
{
private int payroll;
private int hrs;
private int wages;
public ListItem(int roll, int hours, int wag)
{
payroll = roll;
hrs = hours;
wages = wag;
}
public int getPayroll()
{
return payroll;
}
public int getHours()
{
return hrs;
}
public int getWages()
{
return wages;
}
public void setPayroll(int roll)
{
payroll = roll;
}
public void setHrs(int hours)
{
hrs = hours;
}
public void setWages(int wage)
{
wages = wage;
}
public String toString()
{
return "Payroll " + payroll + "\n" + hrs + " hours\n$" + wages;
}
I think your problem is this piece of code in your MainActivity:
Bundle bun = getIntent().getExtras();
if(bun != null)
{
rollList = bun.getIntegerArrayList("rolls");
hourList = bun.getIntegerArrayList("hours");
wageList = bun.getIntegerArrayList("wages");
payRoll = bun.getInt("roll");
}
The getIntent().getExtras() may return a non-null Bundle object but the bundle may not have the keys you are trying to access, in which case all your instance variables will be set to null or zero for int.
You can get around this by simply checking if a particular key exists in the bundle and only setting your variable if it does.
bun.containsKey()
Or you can initialize your variables if they are null after loading them from the bundle.
Try uninstalling the app completely from the device and then try again. This solves the issue at times.
I'm trying to create an app on Android Studio that uses the Belkin WeMo SDK to control the devices around my house. I initialized the mWeMoSDKContext object in the onCreate method as was given in the documentation. However, when I went to run the app I kept getting a NullPointerException and after debugging I found that it was in the lines where I initialized the object. Is there any way to fix this? Also any advice on the app would also be appreciated!
public class MyActivity extends AppCompatActivity implements NotificationListener {
private WeMoSDKContext mWeMoSDKContext = null;
private EditText devicesDisp = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Button onButton = (Button)findViewById(R.id.button);
Button offButton = (Button)findViewById(R.id.button2);
devicesDisp = (EditText)findViewById(R.id.textView2);
TextView device = (TextView) findViewById(R.id.textView);
**mWeMoSDKContext = new WeMoSDKContext(getApplicationContext());
mWeMoSDKContext.addNotificationListener(this);**
}
public class TextTask extends AsyncTask <String, String, String>{
#Override
protected String doInBackground(String... params) {
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
mWeMoSDKContext.refreshListOfWeMoDevicesOnLAN();
}
}
public void onNotify(final String event, final String udn) {
ArrayList<String> udns = mWeMoSDKContext.getListOfWeMoDevicesOnLAN();
int length = udns.size();
if (event.equals(WeMoSDKContext.REFRESH_LIST)) {
if(udns.size() == 0){
devicesDisp.setText("No Devices Detected");
}
else {
for (int i = 0; i < length; i++) {
WeMoDevice device = mWeMoSDKContext.getWeMoDeviceByUDN(udns.get(i));
String tempName = device.getFriendlyName();
devicesDisp.setText(tempName);
}
}
}
}
else if(event.equals(WeMoSDKContext.SET_STATE)) {
int numDevices = udns.size();
if(hourlyPrice > hourlyPriceLimit) {
for (int i = 0; i < numDevices; i++) {
String checkState = "WEMO_DEVICE_OFF";
WeMoDevice checkDevice = mWeMoSDKContext.getWeMoDeviceByUDN(udns.get(i));
if (!checkDevice.getState().equalsIgnoreCase("WEMO_DEVICE_OFF")){
devicesDisp.setText("Device state not changed for" + checkDevice);
}
}
}
else{
for (int i = 0; i < numDevices; i++) {
String checkState = "WEMO_DEVICE_ON";
WeMoDevice checkDevice = mWeMoSDKContext.getWeMoDeviceByUDN(udns.get(i));
if (!checkDevice.getState().equalsIgnoreCase("WEMO_DEVICE_ON")){
devicesDisp.setText("Device state not changed for" + checkDevice);
}
}
}
}
}
public void turnON(View view){
ArrayList<String> devices = mWeMoSDKContext.getListOfWeMoDevicesOnLAN();
int length = devices.size();
for(int i = 0; i < length; i++){
String state = "WEMO_DEVICE_ON";
WeMoDevice deviceState = mWeMoSDKContext.getWeMoDeviceByUDN(devices.get(i));
String type = deviceState.getType();
if (type.equals(WeMoDevice.SWITCH) || type.equals(WeMoDevice.INSIGHT)) {
mWeMoSDKContext.setDeviceState(state, devices.get(i));
}
}
}
public void turnOFF(View view){
ArrayList<String> devices = mWeMoSDKContext.getListOfWeMoDevicesOnLAN();
int length = devices.size();
for(int i = 0; i < length; i++){
String state = "WEMO_DEVICE_OFF";
WeMoDevice deviceState = mWeMoSDKContext.getWeMoDeviceByUDN(devices.get(i));
String type = deviceState.getType();
if (type.equals(WeMoDevice.SWITCH) || type.equals(WeMoDevice.INSIGHT)) {
mWeMoSDKContext.setDeviceState(state, devices.get(i));
}
}
}
protected void onDestroy() {
super.onDestroy();
mWeMoSDKContext.stop();
}
}
UPDATE: Here's the stack trace of the error
java.lang.NullPointerException: Attempt to get length of null array
at org.cybergarage.upnp.ControlPoint.start(ControlPoint.java:976)
at org.cybergarage.upnp.ControlPoint.start(ControlPoint.java:1051)
at com.belkin.wemo.localsdk.WeMoSDKContext$1.run(WeMoSDKContext.java:125)
at java.lang.Thread.run(Thread.java:818)
Im new to Android Developement and currently working on an app that should give me the time between first time clicking a button and second time clicking the button and add it to a currently selected customer.
Current Status of App:
I established a connection to da mySql Database using Volley and a local webservice.
It works to insert my customers and time stamps to the table, but when loading times for a specific customer i get a strange result in one case. I tried debugging it but the app keeps crashing on debugging without a message. When not debugging it doesnt crash but shows weird data.
To the problem:
In my main activity called "ZeitErfassen" i have a button to get an overview of all customers display in a ListView.
I create the Listview with a custom ArrayAdapter because i want to pass my objects to the next Activity where my customers are displayed.
So onCreate of the overview of customers i create a new arraylist and fill it with all customers from my database. this list i pass to my customadapter and then set it as my adapter of the Listview.
Now, when i click on an item, i call a php script and pass the customer_id to the query to fetch all times from database where customer_id = customer_id.
Now the part where i get "strange" data...
1.(Source:ZeitErfassen;Destination:AddCustomer) I create a new customer,example xyz, in the app, data gets passed to the database.
2.(Source:ZeitErfassen;Destination:DisplayCustomer) I call my overview for all customers where the ListView is filled with data as described above. At the end ob the List I see the customer i just created,xyz.
3.Go back to Main Activity(ZeitErfassen)
4.(Source:ZeitErfassen;Destination:DisplayCustomer)I open the overview for all customers again, and it shows my last created user two times! so last entry, xyz, entry before last, xyz!
After that, i can open the view as many times as i want, the customer never gets duplicated again!
The debugger stopps after step 2.
Now when i click on the new customers, it calls the script to fetch the times by customer_id.
One of the xyz entrys display the correct times from database.
The second one, i just found out, display the times where customer_id="". In the database the value for "" is 0.
I have no clue where the second customer suddenly appears from and debugging didnt help me either -.-
When i close the app an open it again, there ist just one entry for the user that was visible twice before closing the app. It doesnt duplicate on opening view...
Here is my code..
Main Activity ZeitErfassen
public class ZeitErfassen extends AppCompatActivity {
public static LinkedList<Kunde> kunden = new LinkedList<Kunde>();
boolean running = false;
long startTime,endTime,totalTime;
private SharedPreferences app_preferences;
private SharedPreferences.Editor editor;
private TextView displayTime;
public Button startEndButton;
private ArrayAdapter<String> adapter;
private Spinner spinner;
public static Kunde selectedCustomer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zeit_erfassen);
//Einstellungen laden
app_preferences = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
startTime= app_preferences.getLong("startTime", 0);
endTime = app_preferences.getLong("endTime", 0);
running = app_preferences.getBoolean("running", false);
displayTime = (TextView)findViewById(R.id.zeit_bei_Kunde);
displayTime.setText((CharSequence) app_preferences.getString("zeitAnzeige", "Zeit bei Kunde"));
startEndButton = (Button)findViewById(R.id.start_Timer);
startEndButton.setText((CharSequence) app_preferences.getString("timerButton", "Start Timer"));
DatabaseHelper.customerFromDatabaseToList(this);
editor = app_preferences.edit();
editor.commit();
}
public void onDestroy() {
super.onDestroy();
editor.putLong("startTime", startTime);
editor.putString("zeitAnzeige", (String) displayTime.getText());
editor.putString("timerButton", (String) startEndButton.getText());
editor.putLong("endTime", endTime);
editor.putLong("totalTime", totalTime);
editor.putBoolean("running", app_preferences.getBoolean("running", false));
editor.commit();
this.finish();
}
public void onResume() {
super.onResume();
// saveCustomers();
// createDropDown();
}
public void startTimer(View view) {
editor = app_preferences.edit();
if(running == false) {
startTime = getTime();
running = true;
editor.putLong("startTime", startTime);
startEndButton.setText("End Timer");
displayTime.setText("Zeitstoppung läuft");
editor.putString("zeitAnzeige", (String) displayTime.getText());
editor.putString("timerButton", (String) startEndButton.getText());
editor.putBoolean("running", true);
editor.commit();
} else {
setSelectedCustomer();
endTime = getTime();
editor.putLong("endTime",endTime);
totalTime = endTime - startTime;
editor.putLong("totalTime", totalTime);
displayTime.setText(formatTime(totalTime));
editor.putString("zeitAnzeige", (String) displayTime.getText());
startEndButton.setText("Start Timer");
editor.putString("timerButton", (String) startEndButton.getText());
running = false;
editor.putBoolean("running", false);
editor.commit();
DatabaseHelper.timeToDatabase(String.valueOf(selectedCustomer.getId()),formatTime(totalTime),this);
// selectedCustomer.saveTimeToCustomer(selectedCustomer, formatTimeForCustomer(totalTime));
}
}
public String formatTime(Long totalTime) {
int hours = (int) ((totalTime / (1000*60*60)) % 24);
int minutes = (int) ((totalTime / (1000*60)) % 60);
int seconds = (int) (totalTime / 1000) % 60;
String time = (String.valueOf(hours) + ":" + String.valueOf(minutes) + ":" + String.valueOf(seconds));
return time;
}
public String formatTimeForCustomer(Long totalTime) {
StringBuilder time = new StringBuilder();
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
time.append((String.valueOf(year) + "." + String.valueOf(month) + "." + String.valueOf(day))).append(formatTime(totalTime));
return time.toString();
}
public void neuerKunde(View view) {
Intent intent = new Intent(this, AddKunde.class);
startActivity(intent);
}
public void kundenĂbersicht(View view) {
// setSelectedCustomer();
Intent intent = new Intent(this, DisplayCustomer.class);
startActivity(intent);
}
public long getTime() {
long millis = System.currentTimeMillis();
return millis;
}
public void setSelectedCustomer() {
if(kunden.size() > 0) {
if (spinner.getSelectedItem().toString() != null) {
String tempCustomer = spinner.getSelectedItem().toString();
for (Kunde k : kunden) {
if (k.getName().equals(tempCustomer)) {
selectedCustomer = k;
}
}
}
}
}
public void createDropDown() {
/*File file = new File(this.getFilesDir(),"kunden.ser"); NOT USED BECAUSE DATABASE WORKS
if(file.exists()) {
Kunde.importFromFile(this);
}*/
if (kunden.size() > 0) {
spinner = (Spinner) findViewById(R.id.chooseCustomer);
// Create an ArrayAdapter using the string array and a default spinner layout
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, DisplayCustomer.namesOfCustomers());
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
}
}
}
DisplayCustomer(Where all customers are displayed with data from Database)
public class DisplayCustomer extends AppCompatActivity {
CustomerAdapter customerAdapter;
public ArrayAdapter<String> adapterCustomerView;
private ListView listCustomerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_customer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ArrayList<Kunde> customerList = getCustomerObjects();
customerAdapter = new CustomerAdapter(this,customerList);
listCustomerView = (ListView)findViewById(R.id.list_View_Customers);
// adapterCustomerView = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, namesOfCustomers());
listCustomerView.setAdapter(customerAdapter);
openCustomerDetails();
}
public static ArrayList<String> namesOfCustomers() {
ArrayList<String> customerNames = new ArrayList<>();
if(ZeitErfassen.kunden.size() > 0 ) {
for (Kunde k : ZeitErfassen.kunden) {
customerNames.add(k.getName());
}
}
return customerNames;
}
public static ArrayList<Kunde> getCustomerObjects() {
ArrayList<Kunde> customerList = new ArrayList<>();
if(ZeitErfassen.kunden.size() > 0 ) {
for (Kunde k : ZeitErfassen.kunden) {
customerList.add(k);
}
}
return customerList;
}
public void openCustomerDetails() {
listCustomerView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Kunde kunde = new Kunde();
kunde = (Kunde)listCustomerView.getItemAtPosition(position);
Intent intent = new Intent(DisplayCustomer.this, DisplayDetailedCustomer.class);
intent.putExtra("selectedCustomerObject",(Parcelable)kunde);
startActivity(intent);
}
});
}
}
My CustomerAdapter to pass data from one intent to another.
public class CustomerAdapter extends ArrayAdapter<Kunde> {
public CustomerAdapter(Context context, ArrayList<Kunde> customerList) {
super(context,0,customerList);
}
public View getView(int position, View convertView, ViewGroup parent) {
//Data for this position
Kunde kunde = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.items_customer_layout, parent, false);
}
// Lookup view for data population
TextView tvName = (TextView) convertView.findViewById(R.id.tvCustomerName);
// Populate the data into the template view using the data object
tvName.setText(kunde.getName());
// Return the completed view to render on screen
return convertView;
}
}
DatabaseHelper Class
public class DatabaseHelper {
public static RequestQueue requestQueue;
public static String host = "http://192.168.150.238/";
public static final String insertUrl = host+"insertCustomer.php";
public static final String showUrl = host+"showCustomer.php";
public static final String insertTimeUrl = host+"insertTime.php";
public static final String showTimeUrl = host+"showTimes.php";
public static void customerFromDatabaseToList(final Context context) {
//Display customer from database
requestQueue = Volley.newRequestQueue(context);
final ArrayList<String> customerNames = new ArrayList<>();
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, showUrl, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray customers = response.getJSONArray("customers");
if(customers.length() > 0) {
for (int i = 0; i < customers.length(); i++) {
JSONObject customer = customers.getJSONObject(i);
String customerName = customer.getString("cus_name");
String customerAddress = customer.getString("cus_address");
int customerID = Integer.valueOf(customer.getString("cus_id"));
if (customerName != null && customerAddress != null) {
try {
Kunde k = new Kunde(customerName, customerAddress, customerID);
if (!listContainsObject(k)) {
ZeitErfassen.kunden.add(k);
}
} catch (Exception e) {
showAlert("Fehler in customerFromDatabaseToListn!", "Fehler", context);
}
} else {
showAlert("Fehler in customerFromDatabaseToListn!", "Fehler", context);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
requestQueue.add(jsonObjectRequest);
}
public static boolean listContainsObject(Kunde cust) {
for(Kunde k : ZeitErfassen.kunden) {
if(k.getId() == cust.getId()) {
return true;
}
}
return false;
}
public static void timeToDatabase(final String customer_id, final String time_value, final Context context) {
requestQueue = Volley.newRequestQueue(context);
StringRequest request = new StringRequest(Request.Method.POST, DatabaseHelper.insertTimeUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
showAlert("Fehler","Fehler bei Verbindung zur Datenbank",context);
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> parameters = new HashMap<String,String>();
parameters.put("customerid",customer_id);
parameters.put("timevalue",time_value);
return parameters;
}
};
requestQueue.add(request);
};
public static void showAlert(String title, String message, Context context) {
// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(context);
// 2. Chain together various setter methods to set the dialog characteristics
builder.setMessage(message)
.setTitle(title);
// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();
}
public static ArrayList<String> timesFromDataBaseToList(final Context context,final int customer_id) {
requestQueue = Volley.newRequestQueue(context);
final String cus_id = String.valueOf(customer_id) ;
final ArrayList<String> customerTimes = new ArrayList<>();
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, showTimeUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject object = new JSONObject(response.toString());
JSONArray times = object.getJSONArray("customertimes");
if (times.length() > 0) {
for (int i = 0; i < times.length(); i++) {
JSONObject jsonObject = times.getJSONObject(i);
String timeValue = jsonObject.getString("time_value");
if (timeValue != null) {
customerTimes.add(timeValue);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(context,"Fehler beim Holen der Zeiten",Toast.LENGTH_LONG).show();
error.printStackTrace();
}
}){
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> parameters = new HashMap<String,String>();
parameters.put("cus_id",cus_id);
return parameters;
}
};
requestQueue.add(jsonObjectRequest);
return customerTimes;
};
}
DisplayDetailedCustomer / Display the times
public class DisplayDetailedCustomer extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_detailed_customer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent getCustomerParcable = getIntent();
Kunde customer = getCustomerParcable.getExtras().getParcelable("selectedCustomerObject");
TextView displayCustomerNameDetailed =(TextView) findViewById(R.id.detailedCustomerViewName);
TextView displayCustomerAddressDetailed =(TextView) findViewById(R.id.detailedCustomerAddress);
ListView timeListView = (ListView)findViewById(R.id.detailedTimeListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, DatabaseHelper.timesFromDataBaseToList(this,customer.getId()));
timeListView.setAdapter(adapter);
displayCustomerNameDetailed.setText(customer.getName());
displayCustomerAddressDetailed.setText(customer.getAdresse());
}
}
Kunde Class / Customer Class with interface Parcelable
public class Kunde implements Serializable,Parcelable {
private String name;
private String adresse;
private int id;
public LinkedList<String> zeiten;
public Kunde(String name, String adresse) throws Exception{
setName(name);
setAdresse(adresse);
zeiten = new LinkedList<String>();
}
public Kunde(String name, String adresse,int id) throws Exception{
setName(name);
setAdresse(adresse);
setId(id);
zeiten = new LinkedList<String>();
}
public Kunde(){};
public void setId(int id) {
this.id = id;
}
public int getId(){
return id;
}
public void setName(String name) throws Exception {
if(name != null) {
this.name = name;
} else throw new Exception("Name ist ungueltig! in setName");
}
public void setAdresse(String adresse) throws Exception{
if(adresse != null) {
this.adresse = adresse;
}else throw new Exception("Adresse ist ungueltig! in setAdresse");
}
public String getName() {
return name;
}
public String getAdresse() {
return adresse;
}
public void saveZeit(Long totalTime) {
zeiten.add(String.valueOf(totalTime));
}
public void saveTimeToCustomer(Kunde customer,String time){
customer.zeiten.add(time);
}
//------------------------------------Parcelable Methods to pass Daata from one Intent to another----------------------------------------
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeString(this.name);
dest.writeString(this.adresse);
// dest.writeList(this.zeiten);
}
// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
public static final Parcelable.Creator<Kunde> CREATOR = new Parcelable.Creator<Kunde>() {
public Kunde createFromParcel(Parcel in) {
return new Kunde(in);
}
public Kunde[] newArray(int size) {
return new Kunde[size];
}
};
// example constructor that takes a Parcel and gives you an object populated with it's values
private Kunde(Parcel in) {
LinkedList<String> zeiten = null;
id = in.readInt();
name = in.readString();
adresse = in.readString();
}
}
Thanks for taking your time!!