I'm making a "Simon says" game as my final project for highschool, and it's mostly done but I have one problem.
Currently, I'm trying to make the buttons light when I press them.
However, they don't seem to light up and the sleep function doesn't really work.
They only change color when the function that displays the next sequence of colors lights up.
Here's the code:
package com.gabie212.simonsays;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
public class GameActivity extends AppCompatActivity implements View.OnClickListener {
private int i = 0, pNum = 0, pIndex = 0,score;
private Thread t = new Thread();
private Thread bt = new Thread();
private Button greenButton;
private Button redButton;
private Button blueButton;
private Button yellowButton;
private Button startButton;
private TextView Score;
private boolean startActivated = false;
private MediaPlayer greenBeep;
private MediaPlayer redBeep;
private MediaPlayer blueBeep;
private MediaPlayer yellowBeep;
private ArrayList<Integer> userColors = new ArrayList<Integer>();
private GameManger gm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
Score = (TextView) findViewById(R.id.ScoreNum);
greenButton = (Button) findViewById(R.id.btnGreen);
redButton = (Button) findViewById(R.id.btnRed);
blueButton = (Button) findViewById(R.id.btnBlue);
yellowButton = (Button) findViewById(R.id.btnYellow);
startButton = (Button) findViewById(R.id.btnStart);
greenButton.setOnClickListener(this);
redButton.setOnClickListener(this);
blueButton.setOnClickListener(this);
yellowButton.setOnClickListener(this);
startButton.setOnClickListener(this);
greenBeep = MediaPlayer.create(this, R.raw.greenbeep);
redBeep = MediaPlayer.create(this, R.raw.redbeep);
blueBeep = MediaPlayer.create(this, R.raw.bluebeep);
yellowBeep = MediaPlayer.create(this, R.raw.yellowbeep);
/*
SharedPreferences sp = getSharedPreferences("score", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
editor.apply();
*/
}
public void start() {
startActivated=true;
gm = new GameManger(this);
Score.setText("0");
lightUp(0);
}
public void beepStop(){
greenBeep.stop();
redBeep.stop();
blueBeep.stop();
yellowBeep.stop();
}
public void lightUp(final int i) {
android.os.Handler handler = new android.os.Handler();
if (i < gm.getRandomColors().size()) //light up code
{
switch (gm.getRandomColors().get(i)) {
case 1:
greenButton.setBackgroundResource(R.drawable.greenlightup);
greenBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
greenButton.setBackgroundResource(R.drawable.green);
lightUp(i+1);
}
}, 500);
break;
case 2:
redButton.setBackgroundResource(R.drawable.redlightup);
redBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
redButton.setBackgroundResource(R.drawable.red);
lightUp(i+1);
}
}, 500);
break;
case 3:
blueButton.setBackgroundResource(R.drawable.bluelightup);
blueBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
blueButton.setBackgroundResource(R.drawable.blue);
lightUp(i+1);
}
}, 500);
break;
case 4:
yellowButton.setBackgroundResource(R.drawable.yellowlightup);
yellowBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
yellowButton.setBackgroundResource(R.drawable.yellow);
lightUp(i+1);
}
}, 500);
break;
}
}
pIndex = 0;
}
#Override
public void onClick(View v) {
if (v.getId() == startButton.getId()) {
start();
} else {
if (startActivated) {
if (v.getId() == greenButton.getId()) {//here is the part where i try to make the buttons change colors
greenBeep.start();
greenButton.setBackgroundResource(R.drawable.greenlightup);
try {
t.sleep(1000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
greenButton.setBackgroundResource(R.drawable.green);
pNum = 1;
}
if (v.getId() == redButton.getId()) { //here is the part where i try to make the buttons change colors
redBeep.start();
redButton.setBackgroundResource(R.drawable.redlightup);
try {
t.sleep(1000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
redButton.setBackgroundResource(R.drawable.red);
pNum = 2;
}
if (v.getId() == blueButton.getId()) { //here is the part where i try to make the buttons change colors
blueBeep.start();
blueButton.setBackgroundResource(R.drawable.bluelightup);
try {
t.sleep(1000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
blueButton.setBackgroundResource(R.drawable.blue);
pNum = 3;
}
if (v.getId() == yellowButton.getId()) {//here is the part where i try to make the buttons change colors
yellowBeep.start();
yellowButton.setBackgroundResource(R.drawable.yellowlightup);
try {
t.sleep(1000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
yellowButton.setBackgroundResource(R.drawable.yellow);
pNum = 4;
}
if (!gm.check(pNum, pIndex)) {
beepStop();
SharedPreferences sp = getSharedPreferences("score", Context.MODE_PRIVATE);
Intent i = null;
score = gm.getRandomColors().size()-1;
if(score > sp.getInt("scoreP3",0)) {
i = new Intent(GameActivity.this, InsertScoreActivity.class);
i.putExtra("score", gm.getRandomColors().size() - 1);
startActivity(i);
}
else {
i = new Intent(GameActivity.this, GameOverActivity.class);
i.putExtra("score", gm.getRandomColors().size() - 1);
startActivity(i);
}
}
pIndex++;
if (pIndex == gm.getRandomColors().size()) {
Score.setText("" + gm.getRandomColors().size() + "");
gm.addColor();
try {
t.sleep(1000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
lightUp(0);//it either performs the color change here beofre the lightup function or it just sleeps and doesn't perform the color change at all
}
}
}
}
}
here's the game helper class:
package com.gabie212.simonsays;
import java.util.ArrayList;
import java.util.Random;
/**
* Created by Ronit on 21/02/2018.
*/
public class GameManger {
private GameActivity gActivity;
static Random rnd = new Random();
private ArrayList<Integer> randomColors;
public GameManger(GameActivity mA)
{
randomColors = new ArrayList<Integer>();
this.gActivity =mA;
randomColors.add(getColor());
}
public void addColor()
{
randomColors.add(getColor());
}
public int getColor()
{
return rnd.nextInt(4)+1;
}
public ArrayList<Integer> getRandomColors()
{
return randomColors;
}
public boolean check(int num, int index)
{
return(randomColors.get(index)==num);
}
}
enter code here
I have some problems.
The sleep doesn't perform, does it have something to do with the way I did it in the if statements? Sleep just doesn't happen in the code I have written.
Color change doesn't happen for some reason and I don't know why it doesn't, maybe it has something to do with the thread.sleep.
Color change happens later in the program than its supposed to. Again, I think it has something to do with the sleep but when I removed the sleep, the color change still happens later in the code.
So I have this little application where you can call from.
In this application, You will be able to log in with your phone-number and get a number from our server (This is not implemented YET)
Depending on "Who you are", our server will give you a number dynamically.
This is not really relevant, but it still has some things to do with my question.
Since our server gives the number, I can't make a "Recent List" with the info I get from Android CallLogs. (It may get numbers A.E "Mom" into your professional contact list, etc etc)
So what I'm doing now, is after each call, insert the info (Name,Number,Date and Duration) Into an Array List.
recentCalls.add(new Recent(aName, aDate, aNumber, "0"));
(0 stands for Seconds, of Duration. Still not completed.)
It would "Save" in the app momentarily, and when the application is fully killed (Or Crashes), everything would be emptied out.
I have considered Saving the Array list in SharedPreferences.
But since we're going to limit the recents to 100, this will be too big.
I have read this: Android Storage Options
Either way, I AM still getting all the call logs from the phone itself, for testing purposes.
My questions are:
How could I save an ArrayList Safely and Efficiently
If I'm not going to work with an ArrayList, How could I "Format" the ACTUAL phone's call_logs to only show numbers dialed from my app. (In order to call "Through" our server, we use "ServerPhoneNumber" + "," + "Inserted PhoneNumber" - Example: 123456789,987654321)
Could I say Check if 1st 10 characters equal to "123456789"? Which is not possible, since it changes the number depending on the person.
Here's my Java Code:
package com.example.dragonphone;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.LightingColorFilter;
import android.net.Uri;
import android.os.Bundle;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.provider.CallLog;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.widget.TextView;
import android.widget.Toast;
public class Tabs extends Activity implements OnClickListener, OnLongClickListener{
TabHost th;
TabSpec specs;
TextView numberfield;
ListView recents;
public String string,number;
private List<Recent> recentCalls = new ArrayList<Recent>();
public int counter;
Button n1,n2,n3,n4,n5,n6,n7,n8,n9,n0,nstar,nhash,sms,contact,call,clear,clearhistory,getinfo;
//ImageView call, clear;
public Vibrator vib;
//public String phoneNumber;
String date = new SimpleDateFormat("dd-MM-yyyy").format(new Date());
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.tabs);
th = (TabHost)findViewById(R.id.tabhost);
numberfield = (TextView) findViewById(R.id.etNumberField);
n1 = (Button) findViewById (R.id.bNumber1);
n2 = (Button) findViewById (R.id.bNumber2);
n3 = (Button) findViewById (R.id.bNumber3);
n4 = (Button) findViewById (R.id.bNumber4);
n5 = (Button) findViewById (R.id.bNumber5);
n6 = (Button) findViewById (R.id.bNumber6);
n7 = (Button) findViewById (R.id.bNumber7);
n8 = (Button) findViewById (R.id.bNumber8);
n9 = (Button) findViewById (R.id.bNumber9);
nstar = (Button) findViewById (R.id.bNumberStar);
n0 = (Button) findViewById (R.id.bNumber0);
nhash = (Button) findViewById (R.id.bNumberHash);
call = (Button) findViewById (R.id.bCall);
sms = (Button) findViewById (R.id.bSMS);
clear = (Button) findViewById (R.id.bClear);
contact = (Button) findViewById (R.id.bContact);
recents = (ListView) findViewById (R.id.recentList);
clearhistory = (Button) findViewById (R.id.bClearHistory);
getinfo = (Button) findViewById (R.id.bGetCallDetails);
populateRecentList();
populateListView();
registerClickCallback();
th.setBackgroundColor(Color.rgb(202, 233, 252));
//n1.getBackground().setColorFilter(new LightingColorFilter(0x000033, 0x000099));
sms.getBackground().setColorFilter(new LightingColorFilter(0xFFFF66, 0xFFFF00));
vib = (Vibrator) getSystemService(VIBRATOR_SERVICE);
n1.setOnClickListener(this);
n2.setOnClickListener(this);
n3.setOnClickListener(this);
n4.setOnClickListener(this);
n5.setOnClickListener(this);
n6.setOnClickListener(this);
n7.setOnClickListener(this);
n8.setOnClickListener(this);
n9.setOnClickListener(this);
nstar.setOnClickListener(this);
n0.setOnClickListener(this);
n0.setOnLongClickListener(this);
nhash.setOnClickListener(this);
call.setOnClickListener(this);
clear.setOnClickListener(this);
clear.setOnLongClickListener(this);
sms.setOnClickListener(this);
contact.setOnClickListener(this);
clearhistory.setOnClickListener(this);
getinfo.setOnClickListener(this);
th.setup();
specs = th.newTabSpec("tag1");
specs.setContent(R.id.Recents);
specs.setIndicator("Recent Calls");
th.addTab(specs);
specs = th.newTabSpec("tag2");
specs.setContent(R.id.Keypad);
specs.setIndicator("Keypad");
th.addTab(specs);
specs = th.newTabSpec("tag3");
specs.setContent(R.id.Sms);
specs.setIndicator("SMS");
th.addTab(specs);
specs = th.newTabSpec("tag4");
specs.setContent(R.id.Ratings);
specs.setIndicator("Rates");
th.addTab(specs);
specs = th.newTabSpec("tag5");
specs.setContent(R.id.Account);
specs.setIndicator("Account");
th.addTab(specs);
}
private void populateRecentList() {
//TODO Auto-generated method stub
recentCalls.add(new Recent("Zach", "01-12-2013", "064555246", "600"));
recentCalls.add(new Recent("Adam", "11-12-2013", "00355563315","510"));
recentCalls.add(new Recent("John", "03-12-2013", "00955587", "100"));
recentCalls.add(new Recent("Jorge", "15-10-2013" , "445559585", "60"));
}
private void populateListView() {
// TODO Auto-generated method stub
ArrayAdapter<Recent> adapter = new MyRecentAdapter();
ListView list = (ListView) findViewById(R.id.recentList);
list.setAdapter(adapter);
}
private class MyRecentAdapter extends ArrayAdapter<Recent>{
public MyRecentAdapter(){
super(Tabs.this, R.layout.recents_view, recentCalls);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
//Make sure we have a view to work with
View itemView = convertView;
if(itemView == null)
{
itemView = getLayoutInflater().inflate(R.layout.recents_view, parent,false);
}
Recent currentCall = recentCalls.get(position);
TextView nameText = (TextView) itemView.findViewById(R.id.tvRecentName);
nameText.setText(currentCall.getName());
TextView numberText = (TextView) itemView.findViewById(R.id.tvRecentNumber);
numberText.setText(currentCall.getPn());
TextView dateText = (TextView) itemView.findViewById(R.id.tvRecentDate);
dateText.setText("" + currentCall.getDate());
TextView durationText = (TextView) itemView.findViewById(R.id.tvRecentDuration);
durationText.setText("" + currentCall.getDuration());
return itemView;
// return super.getView(position, convertView, parent);
}
}
private void registerClickCallback() {
// TODO Auto-generated method stub
ListView list = (ListView) findViewById(R.id.recentList);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked, int position,
long id) {
// TODO Auto-generated method stub
Recent clickedCall = recentCalls.get(position);
String name = clickedCall.getName();
numberfield.setText(clickedCall.getPn());
counter = numberfield.getText().toString().length();
String message = "Calling " + name;
Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, message, duration);
toast.show();
call();
}
});
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch(arg0.getId()){
case R.id.bNumber1:
numberfield.setText(numberfield.getText() + "1");
addCheck();
vib.vibrate(25);
break;
case R.id.bNumber2:
numberfield.setText(numberfield.getText() + "2");
addCheck();
vib.vibrate(25);
break;
case R.id.bNumber3:
numberfield.setText(numberfield.getText() + "3");
addCheck();
vib.vibrate(25);
break;
case R.id.bNumber4:
numberfield.setText(numberfield.getText() + "4");
addCheck();
vib.vibrate(25);
break;
case R.id.bNumber5:
numberfield.setText(numberfield.getText() + "5");
addCheck();
vib.vibrate(25);
break;
case R.id.bNumber6:
numberfield.setText(numberfield.getText() + "6");
addCheck();
vib.vibrate(25);
break;
case R.id.bNumber7:
numberfield.setText(numberfield.getText() + "7");
addCheck();
vib.vibrate(25);
break;
case R.id.bNumber8:
numberfield.setText(numberfield.getText() + "8");
addCheck();
vib.vibrate(25);
break;
case R.id.bNumber9:
numberfield.setText(numberfield.getText() + "9");
addCheck();
vib.vibrate(25);
break;
case R.id.bNumberStar:
numberfield.setText(numberfield.getText() + "*");
addCheck();
vib.vibrate(25);
break;
case R.id.bNumber0:
numberfield.setText(numberfield.getText() + "0");
addCheck();
vib.vibrate(25);
break;
case R.id.bNumberHash:
numberfield.setText(numberfield.getText() + "#");
addCheck();
vib.vibrate(25);
break;
case R.id.bClear:
String number = numberfield.getText().toString();
if(number.length() > 0){
String newNumber = number.substring(0, number.length()-1);
numberfield.setText(newNumber);
deleteCheck();
vib.vibrate(25);
}else{
Context context = getApplicationContext();
CharSequence text = "The numbers are already cleared.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
break;
case R.id.bCall:
call();
break;
case R.id.bContact:
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, 1);
break;
case R.id.bClearHistory:
recentCalls.clear();
CharSequence text = "Your recent list has been cleared.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(this, text, duration);
toast.show();
th.setCurrentTabByTag("tag1");
break;
case R.id.bSMS:
th.setCurrentTabByTag("tag3");
CharSequence text2 = "This function is still under construction..";
int duration2 = Toast.LENGTH_LONG;
Toast toast2 = Toast.makeText(this, text2, duration2);
toast2.show();
break;
case R.id.bGetCallDetails:
getCallDetails();
break;
}
}
private void deleteCheck() {
// TODO Auto-generated method stub
counter --;
if(counter < 14){
numberfield.setTextSize(25); //Set text size when amount goes lower.
}
if(counter >= 14 && counter < 16){
numberfield.setTextSize(20); //Set text size when amount goes lower.
}
if(counter >= 16 && counter < 18){
numberfield.setTextSize(18);
}
if(counter >= 18 && counter < 20){
numberfield.setTextSize(16);
}
}
private void addCheck() {
// TODO Auto-generated method stub
counter++;
if(counter >= 14){
numberfield.setTextSize(20); //Set text size when amount goes higher.
//numberfield.setMaxHeight(10);
}
if(counter >= 16){
numberfield.setTextSize(18); //Set text size when amount goes higher.
}
if(counter >= 18){
numberfield.setTextSize(16); //Set text size when amount goes higher.
}
if(counter >= 20){
numberfield.setTextSize(14); //Set text size when amount goes higher.
}
if(counter < 14){
numberfield.setTextSize(25); //Set text size when amount goes lower.
}
if(counter >= 14 && counter < 16){
numberfield.setTextSize(20); //Set text size when amount goes lower.
}
if(counter >= 16 && counter < 18){
numberfield.setTextSize(18);
}
if(counter >= 18 && counter < 20){
numberfield.setTextSize(16);
}
}
private void getCallDetails() {
StringBuilder sb = new StringBuilder();
Uri contacts = CallLog.Calls.CONTENT_URI;
Cursor managedCursor = this.getContentResolver().query(contacts, null, null, null,CallLog.Calls.DATE + " DESC LIMIT 100");
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
sb.append("Call Details :");
while (managedCursor.moveToNext()) {
String phNumber = managedCursor.getString(number);
String callType = managedCursor.getString(type);
String callDate = managedCursor.getString(date);
String callDayTime = new Date(Long.valueOf(callDate)).toString();
// long timestamp = convertDateToTimestamp(callDayTime);
String callDuration = managedCursor.getString(duration);
String dir = null;
int dircode = Integer.parseInt(callType);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
sb.append("\n----------------------------------");
}
managedCursor.close();
System.out.println(sb);
}
private void call() {
// TODO Auto-generated method stub
if(number.length() > 0){
try {
Intent callIntent = new Intent(Intent.ACTION_CALL);
String dsPhoneNumber = "+34965063314,"; // Dynamic number
//965063064
string = numberfield.getText().toString().trim();
number = "tel:" + dsPhoneNumber + string;
callIntent.setData(Uri.parse(number));
startActivity(callIntent);
//recentCalls.add(new Recent(aName, aDate, aNumber, "0"));
} catch (ActivityNotFoundException activityException) {
Log.e("helloandroid dialing example", "Call failed");
}
}else {
Context context = getApplicationContext();
CharSequence text = "Please insert a phone number or choose a contact.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
#Override
public boolean onLongClick(View arg0) {
// TODO Auto-generated method stub
switch(arg0.getId()){
case R.id.bClear:
if(counter != 0){
counter = 0;
numberfield.setTextSize(25);
numberfield.setText("");
vib.vibrate(100);}
else{
Context context = getApplicationContext();
CharSequence text = "The numbers are already cleared.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
break;
case R.id.bNumber0:
numberfield.setText(numberfield.getText() + "+");
addCheck();
vib.vibrate(25);
break;
}
return true;
}
public void onActivityResult(int reqCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK && data != null) {
Uri uri = data.getData();
Cursor cursor=this.getContentResolver().query(uri, null, null, null, null);
while (cursor.moveToNext()) {
String contactId = cursor.getString(cursor.getColumnIndex(
ContactsContract.Contacts._ID));
String hasPhone = cursor.getString(cursor.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER));
if (Integer.parseInt(cursor.getString( cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
// You now have the number so now query it like this
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,
null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(
phones.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
numberfield.setText(phoneNumber);
counter = numberfield.getText().toString().length();
/*if(counter == 0){
Context context = getApplicationContext();
//CharSequence text = counter;
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, counter, duration);
toast.show();
}*/
}
phones.close();
}
}
}
}
}
Thanks in Advance!
EDIT
private void registerClickCallback() {
// TODO Auto-generated method stub
ListView list = (ListView) findViewById(R.id.recentList);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked, int position,
long id) {
// TODO Auto-generated method stub
Recent clickedCall = recentCalls.get(position);
// String name = clickedCall.getName();
//numberfield.setText(clickedCall.getPn());
counter = numberfield.getText().toString().length();
// String message = getResources().getString(R.string.toastCalling) + " " + name + " " + getResources().getString(R.string.toastCalling2);
Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
//Toast toast = Toast.makeText(context, message, duration);
//toast.show();
call();
}
});
}
This is my current call method. (Commented out stuff since it's not like the old code anymore.)
Basically whenever I click call,
case R.id.bCall:
call();
The Call function:
private void call() {
// TODO Auto-generated method stub
if(numberfield.length() > 0){
try {
Intent callIntent = new Intent(Intent.ACTION_CALL);
String dsPhoneNumber = "+34965063314,";
// Dynamic number
//965063064
String string = numberfield.getText().toString().trim();
number = "tel:" + dsPhoneNumber + string;
callIntent.setData(Uri.parse(number));
startActivity(callIntent);
//recentCalls.add(new Recent(aName, aDate, aNumber, "0"));
} catch (ActivityNotFoundException activityException) {
Log.e("helloandroid dialing example", "Call failed");
}
}else {
Context context = getApplicationContext();
CharSequence text = getResources().getText(R.string.keypadViewToastEmptyNumber);
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
It needs to Insert it in the "List" and show it on the Recents tab.
I've spent a couple of hours trying to solve this, No progress. Thanks in advance!
Edit #2
public View getView(int position, View convertView, ViewGroup parent){
//Make sure we have a view to work with
View itemView = convertView;
if(itemView == null)
{
itemView = getLayoutInflater().inflate(R.layout.recents_view, parent,false);
}
Recent currentCall = recentCalls.get(position);
TextView nameText = (TextView) itemView.findViewById(R.id.tvRecentName);
nameText.setText(currentCall.getName());
TextView numberText = (TextView) itemView.findViewById(R.id.tvRecentNumber);
numberText.setText(currentCall.getPn());
TextView dateText = (TextView) itemView.findViewById(R.id.tvRecentDate);
dateText.setText("" + currentCall.getDate());
TextView durationText = (TextView) itemView.findViewById(R.id.tvRecentDuration);
durationText.setText("" + currentCall.getDuration());
return itemView;
// return super.getView(position, convertView, parent);
}
}
So this is the view of the recents tab. The .getDate/.getDuration etc are changed, What should the "new one" be? So basically read
What I would do is the following:
Get a java.io.File to a local (/data/data/f.q.c.n/files/recents) file
Open a (buffered) FileOutputStream to it
Write the elements of the ArrayList<Recent> to the file
Write the name as byte-array (String.getBytes)
Write the date as a long (since epoch)
Write the number as a string (as there can be different formats)
Write the duration as an int
Note that long and int are fixed-size and therefore can be read easily
You can prefix the byte-array with an int, indicating it's size
Then, of course, you do the same thing in reverse on startup, to rebuild that ArrayList.
Someone called this approach controlled binary serialization. Of course you can have it easier, but it's not really hard to do and you get rid of all reflection (which can have awful performance on early Android devices). This is the fastest (smoothest) approach I can think of.
I didn't choose standard Serialization because it sucks (Tons of reflection and metadata).
Note that SharedPreferences have been successfully (ab-) used to store much larger data than you have.
Example:
IO.java:
import java.io.IOException;
public interface IO {
void write(DataOutputStream out) throws IOException;
void read(DataInputStream in) throws IOException;
}
Recent.java:
import java.io.IOException;
import java.util.Date;
public class Recent implements IO {
private String name, number;
private Date date;
private int duration; // in milliseconds
public Recent(String name, String number, Date date, int duration) {
this.name = name;
this.number = number;
this.date = date;
this.duration = duration;
}
public Recent() {
this(null, null, null, 0);
}
#Override
public void write(DataOutputStream out) throws IOException {
byte[] nameData = name.getBytes("UTF-8");
out.writeInt(nameData.length);
out.write(nameData);
byte[] numberData = number.getBytes("UTF-8");
out.writeInt(numberData.length);
out.write(numberData);
out.writeLong(date.getTime());
out.writeInt(duration);
}
#Override
public void read(DataInputStream in) throws IOException {
int nameDataLength = in.readInt();
if (nameDataLength > 100000) throw new IllegalStateException("Name shouldn't be this long: " + nameDataLength);
byte[] nameData = new byte[nameDataLength];
in.readFully(nameData);
name = new String(nameData, "UTF-8");
int numberDataLength = in.readInt();
if (numberDataLength > 100000) throw new IllegalStateException("Number shouldn't be this long: " + nameDataLength);
byte[] numberData = new byte[numberDataLength];
in.readFully(numberData);
number = new String(numberData, "UTF-8");
date = new Date(in.readLong());
duration = in.readInt();
}
}
RecentsList.java:
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class RecentsList implements IO {
private List<Recent> recents;
public RecentsList() {
recents = new ArrayList<Recent>();
}
public void addRecent(Recent recent) {
recents.add(recent);
}
#Override
public void write(DataOutputStream out) throws IOException {
out.writeInt(recents.size());
for (Recent r : recents) {
r.write(out);
}
}
#Override
public void read(DataInputStream in) throws IOException {
int size = in.readInt();
recents = new ArrayList<Recent>(size);
for (int i = 0; i < size; i++) {
Recent r = new Recent();
r.read(in);
recents.add(r);
}
}
public static void main(String[] args) throws IOException {
RecentsList test = new RecentsList();
// build test data
for (int i = 0; i < 100; i++) {
String iString = Integer.toString(i);
Recent r = new Recent(iString, iString, new Date(), i);
test.addRecent(r);
}
// write
File out = new File("/home/till/recents.bin");
DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(out)));
test.write(dataOut);
dataOut.close();
// read
RecentsList read = new RecentsList();
DataInputStream dataIn = new DataInputStream(new BufferedInputStream(new FileInputStream(out)));
read.read(dataIn);
dataIn.close();
System.out.println("read now contains same data as test if everything went ok");
}
}
Note:
You will wan't to simplify writing and reading a byte-array. I do that myself but didn't include it for briefness (it's long enough already)
The imports for the Data[Input|Output]Stream are missing
You may wan't to change the size for the exception
You can shrink the ints for small numbers
If you have any problems/questions, don't hesitate to comment!
I'm trying to implement a CountDownTimer in an Android Application. This timer will, while running, countdown from a value, than reset, than countdown from a different value. Switching back and force between values until either a set number of rounds have elapsed or the stop button has been pressed. I can get the CountDownTimer samples to work, but I guess I'm missing something here. Below is the applicable button press code;
CounterState state = CounterState.WORKOUT;
private WorkoutTimer workoutTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.workout_stopwatch);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Set up OnClickListeners
((Button) findViewById(R.id.start_button)).setOnClickListener(this);
((Button) findViewById(R.id.stop_button)).setOnClickListener(this);
((Button) findViewById(R.id.reset_button)).setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.start_button:
if (!timer_running) {
timer_running = true;
Log.d(TAG, "clicked on Start Button");
// If the state is unknown, set it to Workout first
int State = state.getStateValue();
if (State == 0) {
state.setStateValue(1);
}
workoutTimer.start();
}
break;
case R.id.stop_button:
Log.d(TAG, "clicked on Stop Button");
if (timer_running); {
timer_running = false;
workoutTimer.cancel();
}
break;
private class WorkoutTimer extends CountDownTimer{
public WorkoutTimer(long interval) {
super(getThisTime(), interval);
Log.d(TAG, "WorkoutTimer Constructed...");
}
TextView digital_display = (TextView) findViewById(R.id.digital_display);
TextView numOfRounds = (TextView) findViewById(R.id.number_of_rounds);
public void onFinish() {
int State = state.getStateValue();
int roundsLeft = 0;
if (State == 1) {
state.setStateValue(2);
} else {
state.setStateValue(1);
}
decrementRounds();
try {
roundsLeft = Integer.parseInt(numOfRounds.getText().toString());
} catch(NumberFormatException nfe) {
roundsLeft = 999;
}
if (roundsLeft > 0 || roundsLeft != 999) {
workoutTimer.start();
}
}
public void onTick(long millisUntilFinished) {
final long minutes_left = ((millisUntilFinished / 1000) / 60);
final long seconds_left = (millisUntilFinished / 1000) - (minutes_left * 60);
final long millis_left = millisUntilFinished % 100;
String time_left = String.format("%02d:%02d.d", minutes_left, seconds_left,
millis_left);
digital_display.setText(time_left);
}
}
private long getThisTime() {
long time = 0;
TextView workout_time = (TextView) findViewById(R.id.workout_time);
TextView rest_time = (TextView) findViewById(R.id.rest_time);
switch(state) {
case WORKOUT:
try {
time = Integer.parseInt(workout_time.getText().toString());
} catch(NumberFormatException nfe) {
time = 999;
}
// time = 90;
Log.d(TAG, "Workout time = " + time);
break;
case REST:
try {
time = Integer.parseInt(rest_time.getText().toString());
} catch(NumberFormatException nfe) {
time = 999;
}
// time = 30;
Log.d(TAG, "Rest time = " + time);
break;
case UNKNOWN:
time = 0;
break;
}
return time;
}
Everything starts up okay, but crashes when I click either button. If I comment out my calls to the workoutTimer, no crash. I never see my log in the constructor of the workoutTimer class, so obviously I'm missing something here. Any help would be appreciated.
-Ian
You have not initialized your workoutTimer. You need to add the following line in your onCreate method.
workoutTimer = new WorkoutTimer(...);
i have a problem with handler in android, i don't understand not display result, this's code:
public class Main extends Activity implements OnClickListener {
private EditText nhap;
private Button btTinh;
private Button btHuy;
private TextView kq;
private ProgressDialog progress;
private Handler handle = new Handler();
private int count = 0;
private String s = "";
private long n;
handlemessage:
Handler mhandle = new Handler() {
#Override
public void handleMessage(Message msg) {
kq.setText(msg.obj.toString());
}
};
onCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
nhap = (EditText) findViewById(R.id.nhap);
btTinh = (Button) findViewById(R.id.btTinh);
btHuy = (Button) findViewById(R.id.btHuy);
kq = (TextView) findViewById(R.id.kq);
btTinh.setOnClickListener(this);
btHuy.setOnClickListener(this);
}
public boolean checkPrime(long n) {
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0)
return false;
}
return true;
}
outprime:
public void outPrime(long t) {
// String s="";
progress.setCancelable(true);
progress.setMessage("File downloading ...");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setProgress(0);
progress.setMax(Integer.parseInt(nhap.getText().toString()));
progress.show();
n = t;
new Thread() {
public void run() {
for (int i = 2; i < n; i++) {
count = i;
if (checkPrime(i))
s = s + i + " ";
handle.post(new Runnable() {
public void run() {
// TODO Auto-generated method stub
progress.setProgress(count);
}
});
}
if (count == n - 1) {
progress.dismiss();
Message msg = handle.obtainMessage(1, (String)s);
handle.sendMessage(msg);
}
}
}.start();
}
onclick:
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btTinh:
progress = new ProgressDialog(this);
outPrime(Long.parseLong(nhap.getText().toString()));
break;
case R.id.btHuy:
nhap.setText("");
break;
}
}}
this's handlemessage:
Handler mhandle = new Handler() {
#Override
public void handleMessage(Message msg) {
kq.setText(msg.obj.toString());
}
};
i don't understand handlemessage don't return value, "kq.setText(msg.obj.toString());" don't display to screen, sorry because my english not good
I think the answer for your question is "Watch out your variable's names!" Look - you've created 2 Handlers - named "mhandle" and "handle". You want to parse message in Handler named "mhandle", but in your Thread send it to "handle", which is doing nothing from your code.
Hope it will help if you still trying to find the answer.
Alright, so i am sort of confused/frustrated.
I have a service that is always running and an activity. Every time the activity is launched and closed the App memory or ram use raises.
All i have in the activity are images and a seekbar.
What would i need to do to stop this as it could very quickly build up!
I also have alot of getter and setters. Such as tv.getText().toString(); and bg.setBackgroundResource(R.drawable.icon);
So, in my onCreate it starts the ID's for the layouts and etc... every time the activity is created the memory or ram used will significantly raise. Is it duplicating the resources or something? It goes up at a constant rate.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(android.view.Window.FEATURE_NO_TITLE);
setContentView(R.layout.lock_screen);
tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
//DATE & TIME STATS
DateLayout = (LinearLayout) findViewById(R.id.DateLayout);
curhour = (TextView) findViewById(R.id.hourText);
curmin = (TextView) findViewById(R.id.minText);
curmonth = (TextView) findViewById(R.id.monthText);
curday = (TextView) findViewById(R.id.dayText);
curactualday = (TextView) findViewById(R.id.actualdayText);
batt = (TextView) findViewById(R.id.batt);
//updateClock();
//PATHS & TARGETS
SliderUnlockPath = (ImageView) findViewById(R.id.slider_unlock_path);
SliderTextAnimation=(AnimationDrawable) SliderUnlockPath.getDrawable();
//SLIDER
seekbar = (SeekBar) findViewById(R.id.seekbar);
seekbar.setOnSeekBarChangeListener( new OnSeekBarChangeListener()
{
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser){
// TODO Auto-generated method stub
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
//SliderUnlockPath.setBackgroundResource(R.drawable.lockscreen_slider_path_light);
SliderUnlockPath.setVisibility(ImageView.INVISIBLE);
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
//SliderUnlockPath.setBackgroundResource(R.drawable.lockscreen_slider_path);
//IF RIGHTMOST (UNLOCK ZONE)
int UnlockZone = seekbar.getProgress();
if (UnlockZone > 86) UnlockZone = 100; {
seekbar.setProgress(UnlockZone);
SliderUnlockPath.setVisibility(ImageView.INVISIBLE);
}
if (UnlockZone == 100) {
mHandler.removeCallbacks(mUpdateTimeTask);
finish();
}
//IF NOT RIGHTMOST
int ResetZone = seekbar.getProgress();
if (ResetZone < 86) ResetZone = 0; {
seekbar.setProgress(ResetZone);
SliderUnlockPath.setVisibility(ImageView.INVISIBLE);
SliderUnlockPath.setVisibility(ImageView.VISIBLE);
//SliderUnlockPath.setBackgroundResource(R.drawable.lockscreen_slider_path);
}
}
});
//WIDGETZONE VIEWFLIPPER
vf = (ViewFlipper) findViewById(R.id.layoutswitcher);
//MUSIC
//MusicLayout = (LinearLayout) findViewById(R.id.MusicLayout);
//MusicInfoLayout = (LinearLayout) findViewById(R.id.MusicInfoLayout);
//UpdateMusicOnStart();
//WEATHER
WeatherTop = (ImageView) findViewById(R.id.WeatherTop);
WeatherTopAnimation();
iconCurrent = (ImageView)findViewById(R.id.iconcurrent);
CurrentLocation = (TextView)findViewById(R.id.CurrentLocation);
CurrentHigh = (TextView)findViewById(R.id.CurrentHigh);
CurrentCondition = (TextView)findViewById(R.id.CurrentCondition);
//CurrentLow = (TextView)findViewById(R.id.CurrentLow);
//Get Location from Main Panel
CurrentLocation.setText(place);
//STRINGS FOR TEXT INFO
//String weatherString = QueryGoogleWeather(place);
//Document weatherDoc = convertStringToDocument(weatherString);
/*if(parseGoogleWeather(weatherDoc)){
//Display Result
String c = currentConditions.condition
+ currentConditions.temp_f
+ currentConditions.temp_c;*/
//+ currentConditions.humidity
//+ currentConditions.wind_condition;
//textCurrent.setText(c);
/*textInfo.setText("city: " + forecastInformation.city + "\n"
+ "postal code: " + forecastInformation.postal_code + "\n"
+ "forecast date: " + forecastInformation.forecast_date + "\n"
+ "current date time: " + forecastInformation.current_date_time + "\n"
+ "unit: " + forecastInformation.unit_system);*/
//CurrentLocation.setText(forecastInformation.city);
//if (iLockerMain.TEMPSCALE.isChecked()) {
//CurrentHigh.setText(currentConditions.temp_f+"°"+"F");
//} else {
//CurrentHigh.setText(currentConditions.temp_c+"°"+"C");
//}
//CurrentCondition.setText(currentConditions.condition);
//Bitmap bm = LoadIcon(currentConditions.icon);
//iconCurrent.setImageBitmap(bm);
/*if (CurrentCondition.getText().toString().equals("Overcast")) {
iconCurrent.setBackgroundResource(R.drawable.cloudy3small);
} else if (CurrentCondition.getText().toString().equals("Light rain")) {
iconCurrent.setBackgroundResource(R.drawable.light_rainsmall);
} else if (CurrentCondition.getText().toString().equals("Light snow")) {
iconCurrent.setBackgroundResource(R.drawable.snow3small);
}*/
mHandler = new Handler();
}
#Override
public void onResume(){
//updateClock();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 100);
super.onResume();
}
#Override
public void onPause(){
//unregisterReceiver(mReceiver);
mHandler.removeCallbacks(mUpdateTimeTask);
super.onPause();
}
Are you releasing all your allocations in onDestroy()?