I want develop Pomodoro app. I have edittext, countdowntimer, listview on my project. My app can work.And I have a lot of text on my list. my 3. countdown timer on finish I add text my listview. How can I save listview with sharedpreferences? and How Can I do this . Thanks A lot of
main_activty.class
public class pomodoro extends AppCompatActivity {
Button baslat,backhome,bitir;
EditText edittextcalisma,edittextmola;
CountDownTimer calisma,mola;
ArrayList<String> list = new ArrayList<String>();
ArrayAdapter arrayAdapter;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pomodoro);
listView=(ListView)findViewById(R.id.listv);
arrayAdapter = new ArrayAdapter<String>(
this,R.layout.list_view,R.id.textitem, list);
listView.setAdapter(arrayAdapter);
bitir=findViewById(R.id.bitirbutton);
baslat = findViewById(R.id.baslatbutton);
edittextcalisma = findViewById(R.id.edittextcalisma);
edittextmola = findViewById(R.id.edittextmola);
baslat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
closeKeyboard();
final int molapo = Integer.valueOf(edittextmola.getText().toString());
final int calismapo = Integer.valueOf(edittextcalisma.getText().toString());
if (calismapo <= 600 && molapo <= 600 && calismapo > 0 && molapo>0){
calisma = new CountDownTimer(calismapo * 60000, 1000) {
#Override
public void onTick(long millis) {
}
#Override
public void onFinish() {
final int molapo = Integer.valueOf(edittextmola.getText().toString());
mola = new CountDownTimer(molapo * 60000, 1000) {
#Override
public void onTick(long millis) {
}
#Override
public void onFinish() {
pomodoro.setText("Bitti");
CountDownTimer bekle = new CountDownTimer(5000, 1000) {
#Override
public void onTick(long millis) {
}
#Override
public void onFinish() {
Calendar c = Calendar.getInstance();
SimpleDateFormat dateformat = new SimpleDateFormat("dd-MMMM-yyyy HH:mm");
String datetime = dateformat.format(c.getTime());
list.add("Çalışma Süresi : " + calismapo +" dk "+"\n"+ "Mola Süresi : " + molapo+" dk " +"\n" + datetime);
arrayAdapter.notifyDataSetChanged();
}
}.start();
}
}.start();
}
}.start();
}
}
});
}
}
you need to put metadata in LUNCHER activity in order to work
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.shortcuts"
android:resource="#xml/shortcuts" />
</activity>
Related
This is ClassifierActivity.java file which is rendering by default:
package org.tensorflow.lite.examples.classification;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Typeface;
import android.media.ImageReader.OnImageAvailableListener;
import android.os.SystemClock;
import android.util.Size;
import android.util.TypedValue;
import android.widget.Toast;
import java.io.IOException;
import java.util.List;
import org.tensorflow.lite.examples.classification.env.BorderedText;
import org.tensorflow.lite.examples.classification.env.Logger;
import org.tensorflow.lite.examples.classification.tflite.Classifier;
import org.tensorflow.lite.examples.classification.tflite.Classifier.Device;
import org.tensorflow.lite.examples.classification.tflite.Classifier.Model;
public class ClassifierActivity extends CameraActivity implements OnImageAvailableListener {
private static final Logger LOGGER = new Logger();
private static final Size DESIRED_PREVIEW_SIZE = new Size(640, 480);
private static final float TEXT_SIZE_DIP = 10;
private Bitmap rgbFrameBitmap = null;
private long lastProcessingTimeMs;
private Integer sensorOrientation;
public Classifier classifier;
private BorderedText borderedText;
/** Input image size of the model along x axis. */
private int imageSizeX;
/** Input image size of the model along y axis. */
private int imageSizeY;
#Override
protected int getLayoutId() {
return R.layout.camera_connection_fragment;
}
#Override
protected Size getDesiredPreviewFrameSize() {
return DESIRED_PREVIEW_SIZE;
}
#Override
public void onPreviewSizeChosen(final Size size, final int rotation) {
final float textSizePx =
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DIP, getResources().getDisplayMetrics());
borderedText = new BorderedText(textSizePx);
borderedText.setTypeface(Typeface.MONOSPACE);
recreateClassifier(getModel(), getDevice(), getNumThreads());
if (classifier == null) {
LOGGER.e("No classifier on preview!");
return;
}
previewWidth = size.getWidth();
previewHeight = size.getHeight();
sensorOrientation = rotation - getScreenOrientation();
LOGGER.i("Camera orientation relative to screen canvas: %d", sensorOrientation);
LOGGER.i("Initializing at size %dx%d", previewWidth, previewHeight);
rgbFrameBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
}
#Override
protected void processImage() {
rgbFrameBitmap.setPixels(getRgbBytes(), 0, previewWidth, 0, 0, previewWidth, previewHeight);
final int cropSize = Math.min(previewWidth, previewHeight);
runInBackground(
new Runnable() {
#Override
public void run() {
if (classifier != null) {
final long startTime = SystemClock.uptimeMillis();
final List<Classifier.Recognition> results =
classifier.recognizeImage(rgbFrameBitmap, sensorOrientation);
lastProcessingTimeMs = SystemClock.uptimeMillis() - startTime;
LOGGER.v("Detect: %s", results);
runOnUiThread(
new Runnable() {
#Override
public void run() {
showResultsInBottomSheet(results);
showFrameInfo(previewWidth + "x" + previewHeight);
showCropInfo(imageSizeX + "x" + imageSizeY);
showCameraResolution(cropSize + "x" + cropSize);
showRotationInfo(String.valueOf(sensorOrientation));
showInference(lastProcessingTimeMs + "ms");
}
});
}
readyForNextImage();
}
});
}
#Override
protected void onInferenceConfigurationChanged() {
if (rgbFrameBitmap == null) {
// Defer creation until we're getting camera frames.
return;
}
final Device device = getDevice();
final Model model = getModel();
final int numThreads = getNumThreads();
runInBackground(() -> recreateClassifier(model, device, numThreads));
}
private void recreateClassifier(Model model, Device device, int numThreads) {
if (classifier != null) {
LOGGER.d("Closing classifier.");
classifier.close();
classifier = null;
}
if (device == Device.GPU && model == Model.QUANTIZED) {
LOGGER.d("Not creating classifier: GPU doesn't support quantized models.");
runOnUiThread(
() -> {
Toast.makeText(this, "GPU does not yet supported quantized models.", Toast.LENGTH_LONG)
.show();
});
return;
}
try {
LOGGER.d(
"Creating classifier (model=%s, device=%s, numThreads=%d)", model, device, numThreads);
classifier = Classifier.create(this, model, device, numThreads);
} catch (IOException e) {
LOGGER.e(e, "Failed to create classifier.");
}
// Updates the input image size.
imageSizeX = classifier.getImageSizeX();
imageSizeY = classifier.getImageSizeY();
}
}
I created a new activity named Main.java and I want this activity to render first and pass it ClassifierActivity.java as intent by click on button:
package org.tensorflow.lite.examples.classification;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.VideoView;
public class Main extends AppCompatActivity {
VideoView videoView;
private Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// hide title bar
getSupportActionBar().hide();
// set button on click to scan where open the camera
btn=(Button)findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openActivity();
}
});
videoView = findViewById(R.id.videoview);
Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.turkey);
videoView.setVideoURI(uri);
videoView.start();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
}
});
}
protected void openActivity(){
Intent i = new Intent(this, ClassifierActivity.class);
startActivity(i);
}
#Override
protected void onPostResume() {
videoView.resume();
super.onPostResume();
}
#Override
protected void onRestart() {
videoView.start();
super.onRestart();
}
#Override
protected void onPause() {
videoView.suspend();
super.onPause();
}
#Override
protected void onDestroy() {
videoView.stopPlayback();
super.onDestroy();
}
}
This is old AndroidManifest.xml (app running successfully)
<activity
android:name=".ClassifierActivity"
android:label="#string/activity_name_classification"
android:screenOrientation="portrait"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
And I want to run Main first. So, I changed android:name=".ClassifierActivity" from old AndroidManifest.xml to android:name=".Main" (app is stop running):
<activity
android:name=".Main"
android:label="#string/activity_name_classification"
android:screenOrientation="portrait"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
All activities need to be defined in the manifest.
You are replacing the original Activity with the new one and now the old one is not defined. So you just need to add it back.
<application
...
/>
<activity
android:name=".ClassifierActivity"
android:label="#string/activity_name_classification"
android:screenOrientation="portrait"
android:exported="true" >
</activity>
<activity
android:name=".Main"
android:label="#string/activity_name_classification"
android:screenOrientation="portrait"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I'm creating a timer app that utilizes a thread. When I exit the app using the home button the timer is running fine. Usually, when the time is up a dialog is launched that asks the user for some input. This works completely fine if the app is in its onResume() state, however when the app is in its onStop() state the dialog will not launch and an error is thrown.
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
How can I make it so that when the time is up and the app is NOT in the foreground the dialog is still launched. My initial thought was to save the time remaining in the bundle, but the time remaining is changing for every single tick. Then I thought about storing a boolean in the bundle mTimeRunning. However, when the time is up this value must also change. So now I'm drawing a blank. What can I possibly do so that the dialog is launched when the app is not in the foreground?
TimerActivity.java
public class TimerActivity extends AppCompatActivity implements TimeDialogFragment.sendMinutes,
TimeFinishDialogFragment.sendResponse, BreakFinishDialogFragment.userResponse {
// Variable to log activity state
private static final String TAG = "TimerActivity";
private static final boolean DEBUG = true;
// ^^ Variable used to log acitivty state
private Handler mHandler;
private Runnable mRunnable;
//private static final long START_TIME_MILLISECONDS = 600000;
// Below start time is for development purposes only
private static long mStartTime = 10000;
private long mTimeRemaining = mStartTime;
private boolean mTimeRunning;
private boolean mBreakTime = false;
private ProgressBar mTimeBar;
private TextView mTime;
private Button mStartPause;
private Button mSetTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
if(DEBUG) Log.d(TAG, "+ onCreate() +");
mHandler = new Handler();
mTimeBar = findViewById(R.id.time_bar);
mTime = findViewById(R.id.text_view_time);
mStartPause = findViewById(R.id.button_start_pause);
mSetTime = findViewById(R.id.button_set_time);
updateCountDownText();
mTimeBar.setMax((int) mTimeRemaining);
mSetTime.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//FragmentManager manager = getSupportFragmentManager();
DialogFragment setTime = new TimeDialogFragment();
setTime.show(getFragmentManager(),"SET_TIME_DIALOG");
}
});
mStartPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(mTimeRunning){
//pauseTimer();
mTimeRunning = false;
mStartPause.setText("Start");
mHandler.removeCallbacks(mRunnable);
}else{
//startTimer();
timer();
}
}
});
}
// Using a handler + anon runnable
private void timer(){
mRunnable = new Runnable() {
#Override
public void run() {
mTimeRunning = true;
mStartPause.setText("Pause");
mTimeRemaining = mTimeRemaining - 1000;
updateCountDownText();
mTimeBar.incrementProgressBy(1000);
if(mTimeRemaining > 0) {
mHandler.postDelayed(this, 1000);
}else{
// if breaktime is false
if(!mBreakTime) {
DialogFragment dialog = new TimeFinishDialogFragment();
dialog.show(getFragmentManager(),"TIME_FINISH_DIALOG");
mTimeRunning = false;
}else{
// launch break time up dialog.
mBreakTime = false;
DialogFragment dialog = new BreakFinishDialogFragment();
dialog.show(getFragmentManager(), "BREAK_FINSIH_DIALOG");
}
}
}
};
mHandler.postDelayed(mRunnable,1000);
}
public void updateCountDownText(){
int min = (int) (mTimeRemaining / 1000) / 60;
int sec = (int) (mTimeRemaining / 1000) % 60;
String formattedString = String.format(Locale.getDefault(), "%02d:%02d", min, sec);
mTime.setText(formattedString);
}
public void setCountDownText(long time){
int min = (int) (time / 1000) / 60;
int sec = (int) (time / 1000) % 60;
String formattedString = String.format(Locale.getDefault(), "%02d:%02d", min, sec);
mTime.setText(formattedString);
}
#Override
public void userTime(int minutes) {
TimerActivity.mStartTime = (minutes * 60) * 1000;
mTimeRemaining = TimerActivity.mStartTime;
mTimeBar.setMax((int) mTimeRemaining);
setCountDownText(mTimeRemaining);
}
#Override
public void sendResponse(int val) {
if(val == -1){
mTimeRemaining = TimerActivity.mStartTime;
mTimeBar.setMax((int) mTimeRemaining);
updateCountDownText();
mTimeBar.setProgress(0);
mStartPause.setText("Start");
}else if(val == 1) {
mBreakTime = true;
mTimeRemaining = 15000;
mTimeBar.setMax((int) mTimeRemaining);
setCountDownText(mTimeRemaining);
mTimeBar.setProgress(0);
mStartPause.setVisibility(View.INVISIBLE);
timer();
}else {
mTimeRemaining = TimerActivity.mStartTime;
mTimeBar.setMax((int) mTimeRemaining);
updateCountDownText();
mTimeBar.setProgress(0);
timer();
}
}
#Override
public void userResponse(int val) {
if(val < 0) {
// user clicked cance
mTimeRemaining = TimerActivity.mStartTime;
mTimeBar.setMax((int) mTimeRemaining);
updateCountDownText();
mTimeBar.setProgress(0);
mStartPause.setText("Start");
}else {
mTimeRemaining = TimerActivity.mStartTime;
mTimeBar.setMax((int) mTimeRemaining);
updateCountDownText();
mTimeBar.setProgress(0);
timer();
}
mStartPause.setVisibility(View.VISIBLE);
}
TimeFinishedDialog.java
public class TimeFinishDialogFragment extends DialogFragment implements View.OnClickListener{
private Button mCancel;
private Button mSkip;
private Button mStartBreak;
private sendResponse mResponse;
interface sendResponse{
void sendResponse(int val);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
//return super.onCreateDialog(savedInstanceState);
View view = LayoutInflater.from(getActivity()).inflate(R.layout.time_finish_dialog_fragment, null, false);
mCancel = view.findViewById(R.id.button_cancel);
mSkip = view.findViewById(R.id.button_skip);
mStartBreak = view.findViewById(R.id.button_start_break);
mCancel.setOnClickListener(this);
mSkip.setOnClickListener(this);
mStartBreak.setOnClickListener(this);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view)
.setTitle("Start Break?");
AlertDialog dialog = builder.create();
dialog.setContentView(view);
return dialog;
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.button_cancel:
mResponse.sendResponse(-1);
getDialog().dismiss();
break;
case R.id.button_skip:
mResponse.sendResponse(0);
getDialog().dismiss();
break;
case R.id.button_start_break:
mResponse.sendResponse(1);
getDialog().dismiss();
break;
default:
break;
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try{
mResponse = (sendResponse) getActivity();
}catch (ClassCastException e){
System.out.println("Error: " + e);
}
}
}
when the time is up and the app is NOT in the foreground the dialog is still launched
You should not be doing this since this will interrupt the user from doing other work which they might be doing at that time and this can be irritating.
What can I possibly do so that the dialog is launched when the app is not in the foreground?
You can show the dialog only the user is actively using your application or you can fall back to show a notification when the user is not using the app.
And if you desperately want to show a dialog, you can try a dialog themed activity
I am trying to build an app in which the action bar has a countdown timer view. I succeeded in doing it but, when I close the app and reopen, the countdown restarts. What I need is the countdown should not stop till it completes its time even if I close or minimize the app. I tried this code:
final long[] timer = {2700000};
getMenuInflater().inflate(R.menu.menu_main, menu);
final MenuItem counter = menu.findItem(R.id.counter);
new CountDownTimer(timer[0], 1000) {
public void onTick(long millisUntilFinished) {
long millis = millisUntilFinished;
String hms = (TimeUnit.MILLISECONDS.toHours(millis))+":"+(TimeUnit.MILLISECONDS.toMinutes(millis) -TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)))+":"+ (TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
counter.setTitle(hms);
timer[0] = millis;
}
public void onFinish() {
counter.setTitle("done!");
}
}.start();
return true;
Mr. donnfelker Had written countdown timer service on his bootstrap android demo. given link is open source Android bootstrap you will find this service class. will give you hint for how this will done.
public class TimerService extends Service {
#Inject protected Bus eventBus;
#Inject NotificationManager notificationManager;
private boolean timerRunning = false;
private boolean timerStarted;
private long base;
private long currentRunningTimeInMillis;
private long pausedBaseTime;
private boolean isPaused;
public static final int TICK_WHAT = 2;
private NotificationCompat.Builder b;
private String messageFormat;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
BootstrapApplication.component().inject(this);
// Register the bus so we can send notifications.
eventBus.register(this);
}
#Override
public void onDestroy() {
// Unregister bus, since its not longer needed as the service is shutting down
eventBus.unregister(this);
notificationManager.cancel(TIMER_NOTIFICATION_ID);
Timber.d("Service has been destroyed");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!timerStarted) {
timerStarted = true;
startTimer();
// Run as foreground service: http://stackoverflow.com/a/3856940/5210
// Another example: https://github.com/commonsguy/cw-android/blob/master/Notifications/FakePlayer/src/com/commonsware/android/fakeplayerfg/PlayerService.java
startForeground(TIMER_NOTIFICATION_ID, getNotification(getString(R.string.timer_running)));
}
return START_NOT_STICKY;
}
#Produce
public TimerTickEvent produceTickEvent() {
updateNotification(getTimerRunningMessage(currentRunningTimeInMillis));
return new TimerTickEvent(currentRunningTimeInMillis);
}
#Produce
public TimerPausedEvent produceTimerIsPausedEvent() {
return new TimerPausedEvent(isPaused);
}
#Subscribe
public void onStopEvent(StopTimerEvent stopEvent) {
timerHandler.removeMessages(TICK_WHAT);
stopSelf();
}
#Subscribe
public void onPauseEvent(PauseTimerEvent pauseEvent) {
pauseTimer();
}
/**
* Pauses the active running timer and updates the notification in the status bar.
*/
private void pauseTimer() {
updateNotification(getString(R.string.timer_is_paused));
timerHandler.removeMessages(TICK_WHAT);
pausedBaseTime = SystemClock.elapsedRealtime() - base;
timerRunning = false;
isPaused = true;
produceTimerIsPausedEvent();
}
#Subscribe
public void onResumeTimerEvent(ResumeTimerEvent resumeTimerEvent) {
startTimer();
}
private void startTimer() {
startChronoTimer();
notifyTimerRunning();
}
private void startChronoTimer() {
base = SystemClock.elapsedRealtime();
// If coming from a paused state, then find our true base.
if (pausedBaseTime > 0)
base = base - pausedBaseTime;
isPaused = false;
updateRunning();
}
/**
* Starts the generic timer.
*/
private void updateRunning() {
if (timerStarted != timerRunning) {
if (timerStarted) {
dispatchTimerUpdate(SystemClock.elapsedRealtime());
timerHandler.sendMessageDelayed(Message.obtain(timerHandler, TICK_WHAT), 1000);
} else {
timerHandler.removeMessages(TICK_WHAT);
}
timerRunning = timerStarted;
}
}
private Handler timerHandler = new Handler() {
public void handleMessage(Message m) {
if (timerRunning) {
dispatchTimerUpdate(SystemClock.elapsedRealtime());
sendMessageDelayed(Message.obtain(this, TICK_WHAT), 1000);
}
}
};
private void dispatchTimerUpdate(long now) {
currentRunningTimeInMillis = now - base;
Timber.d("Elapsed Seconds: " + currentRunningTimeInMillis / 1000);
eventBus.post(produceTickEvent());
}
private void notifyTimerRunning() {
updateNotification(getTimerRunningMessage(currentRunningTimeInMillis));
produceTimerIsPausedEvent();
}
private String getTimerRunningMessage(long millis) {
if(Strings.isEmpty(messageFormat)) {
messageFormat = getString(R.string.timer_running);
}
return String.format(messageFormat, TimeUtil.formatTime(millis));
}
private void updateNotification(String message) {
notificationManager.notify(TIMER_NOTIFICATION_ID, getNotification(message));
}
/**
* Creates a notification to show in the notification bar
*
* #param message the message to display in the notification bar
* #return a new {#link Notification}
*/
private Notification getNotification(String message) {
final Intent i = new Intent(this, BootstrapTimerActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, i, 0);
if(Strings.notEmpty(message)) {
return getNotificationBuilder(message, pendingIntent)
.setContentText(message)
.build();
} else {
return getNotificationBuilder(message, pendingIntent).build();
}
}
/**
* Resuse the same notification builder.
* #param message
* #param pendingIntent
* #return
*/
private NotificationCompat.Builder getNotificationBuilder(String message, PendingIntent pendingIntent) {
if(b == null) {
b = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.app_name))
.setSmallIcon(R.drawable.ic_stat_ab_notification)
.setContentText(message)
.setAutoCancel(false)
.setOnlyAlertOnce(true)
.setOngoing(true)
.setWhen(System.currentTimeMillis())
.setContentIntent(pendingIntent);
}
return b;
}
}
If you want to it in activity. Check below demo
MainActivity:
public class MainActivity extends AppCompatActivity {
Context context;
private SharedPreferences mPrefs;
private CountDownTimer countDownTimer;
// here is prefs key
String Key = "TIME";
long time = 30000; // 30 sec
EditText number;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
number = (EditText) findViewById(R.id.foodName);
mPrefs = this.getSharedPreferences("myAppPrefs", Context.MODE_PRIVATE);
if (mPrefs.getLong(Key, 0) == 0) {
mPrefs.edit().putLong(Key, time).apply();
} else {
time = mPrefs.getLong(Key, time);
}
Log.d("App Open Time ", time + "");
startCount();
}
private void startCount() {
countDownTimer = new CountDownTimer(time, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mPrefs.edit().putLong(Key, millisUntilFinished).apply();
number.setText(millisUntilFinished/1000 + "");
Log.d("Remaining time", millisUntilFinished/1000 + "");
}
#Override
public void onFinish() {
Log.d("finished time", time + "");
mPrefs.edit().putLong(Key, 0).apply();
number.setText(time + "");
}
};
countDownTimer.start();
}
#Override
protected void onPause() {
super.onPause();
countDownTimer.cancel();
Log.d("App in background", "with " + time);
}
}
layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/base"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="#color/white"
android:orientation="horizontal"
android:weightSum="10">
<EditText
android:id="#+id/foodName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="64dp"
android:layout_marginRight="64dp"
android:hint="Food name"
android:inputType="textCapWords"
android:textColor="#color/colorPrimaryDark"
android:textColorHint="#color/colorPrimaryDark"
android:textSize="32sp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Manifest:
<activity
android:name=".activity.MainActivity"
android:configChanges="orientation|screenSize">
</activity>
I am new to android. I have main activity from which I need to call different classes to perform different functions. But whenever I call two classes at same time, only the last intent is called. Can someone suggest a way to call 2 or more classes at the same time in an activity. Thank you
Below is my code example
Main Activity
public class MainActivity extends AppCompatActivity {
public Api mApi;
Button data;
#Override
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
data = (Button) findViewById(R.id.button2);
//calling sygic truck api and implementing sygic call back
mApi = Api.init(getApplicationContext(), "com.sygic.truck", "com.sygic.truck.SygicService", mApiCallback);
//connecting sygic app
mApi.connect();
data.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1 = new Intent(getApplicationContext(), locationInfo.class);
Intent intent2 = new Intent(getApplicationContext(), routeInfo.class);
Intent[] list = new Intent[2];
list[0] = intent1;
list[1] = intent2;
startActivities(list);
}
});
}
}
locationInfo class
public class locationInfo extends AppCompatActivity {
public Api mApi;
public TextView coordinates;
public String currentLocation = "";
public String longitude;
public String latitude;
public Button data;
public String altitude, speed;
public int speedLimit;
//calling gps class from sygic lib
GpsPosition gpsPos = new GpsPosition();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinates = (TextView) findViewById(R.id.textView);
// sygicGetData();
try {
Log.v("debug", "Location is...1" );
boolean satInfo = true;
int maxTime = 0;
gpsPos = ApiNavigation.getActualGpsPosition(satInfo, maxTime);
longitude = String.valueOf(gpsPos.getLongitude());
latitude = String.valueOf(gpsPos.getLatitude());
altitude = String.valueOf(gpsPos.getAltitude());
speed = String.valueOf(gpsPos.getSpeed());
speedLimit = ApiInfo.getCurrentSpeedLimit(maxTime);
Log.v("debug", "Location is...2" );
Position pos = new Position();
pos.setPosition(gpsPos.getLongitude(), gpsPos.getLatitude());
currentLocation = ApiLocation.getLocationAddressInfo(pos, maxTime);
coordinates.setText("\n" + "Current Location:" + currentLocation + "\n" + "Longitude:" + longitude + "\n" + "Latitude:" + latitude +
"\n" + "Altitude:" + altitude + "\n" + "Current Speed:" + speed +
"\n" + "Speed Limit:" + speedLimit);
} catch (GpsException e) {
Log.e("GpsPosition", "Error code:" + e.getCode());
} catch (InvalidLocationException e) {
Log.e("Location", "Error code:" + e.getCode());
} catch (GeneralException e) {
e.printStackTrace();
}
}
}
routeInfo class
public class routeInfo extends AppCompatActivity {
public String remainingDistance, remainingTime;
public String totalDistance, totalTime;
public Button data;
public TextView coordinates;
public RouteInfo routeInfo;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinates = (TextView)findViewById(R.id.textView2);
// sygicGetData();
try {
boolean info = true;
int maxTime = 0;
routeInfo = ApiNavigation.getRouteInfo(info, maxTime);
totalDistance = String.valueOf(routeInfo.getTotalDistance());
remainingDistance = String.valueOf(routeInfo.getRemainingDistance());
totalTime = String.valueOf(routeInfo.getTotalTime());
remainingTime = String.valueOf(routeInfo.getRemainingTime());
coordinates.setText("\n" + "Total Travel Distance:" + totalDistance + "\n" + "Remaining Travel Distance:" + remainingDistance + "\n" + "Total Travel Time:" + totalTime + "\n" +
"Remaining Travel Time:" + remainingTime + "\n");
} catch (GpsException e) {
Log.e("GpsPosition", "Error code:" + e.getCode());
} catch (InvalidLocationException e) {
Log.e("Location", "Error code:" + e.getCode());
} catch (GeneralException e) {
e.printStackTrace();
}
}
}
Android Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jackfruit.sygicdata4">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".getters.locationInfo"></activity>
<activity android:name=".getters.routeInfo"></activity>
</application>
</manifest>
Ok,
startActivities()
is used to construct something called a synthetic back stack.
In an app when you move from 1 activity to another without invoking a
finish()
in any of the activities you construct something called a "backstack". It is called a back stack because it is the stack of activities that get restored when you keep pressing the back button.
If you wanted to artificially create a backstack you would
-startActivities()
What this does is artificially insert everything but the activity of the last intent into the backstack.
If you wanted to run activit 1 and then run activity2
just call
startActivity()
on them separately
If you want the 2 to tasks to run in parallel you need to use something called "AsyncTask". Literature here
I am getting error message when I start another activity named Task. The application have 4 image buttons (the other buttons image open correctly. When I click "TaskViewer"(ImageButton2) appears the error.
The activity that attempts to open: (ViewTask)
public class ViewTask extends Activity {
protected TaskerDbHelper db;
List<Task> list;
MyAdapter adapt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_task);
db = new TaskerDbHelper(this);
list = db.getAllTasks();
adapt = new MyAdapter(this, R.layout.list_inner_view, list);
ListView listTask = (ListView) findViewById(R.id.listView1);
listTask.setAdapter(adapt);
}
public void addTaskNow(View v) {
EditText t = (EditText) findViewById(R.id.editText1);
String s = t.getText().toString();
if (s.equalsIgnoreCase("")) {
Toast.makeText(this, "enter the task description first!!",
Toast.LENGTH_LONG);
} else {
Task task = new Task(s, 0);
db.addTask(task);
Log.d("tasker", "data added");
t.setText("");
adapt.add(task);
adapt.notifyDataSetChanged();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_view_task, menu);
return true;
}
private class MyAdapter extends ArrayAdapter<Task> {
Context context;
List<Task> taskList = new ArrayList<Task>();
int layoutResourceId;
public MyAdapter(Context context, int layoutResourceId,
List<Task> objects) {
super(context, layoutResourceId, objects);
this.layoutResourceId = layoutResourceId;
this.taskList = objects;
this.context = context;
}
/**
* This method will DEFINe what the view inside the list view will
* finally look like Here we are going to code that the checkbox state
* is the status of task and check box text is the task name
*/
#Override
public View getView(int position, View convertView, ViewGroup parent) {
CheckBox chk = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_inner_view,
parent, false);
chk = (CheckBox) convertView.findViewById(R.id.chkStatus);
convertView.setTag(chk);
chk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
Task changeTask = (Task) cb.getTag();
changeTask.setStatus(cb.isChecked() == true ? 1 : 0);
db.updateTask(changeTask);
Toast.makeText(
getApplicationContext(),
"Clicked on Checkbox: " + cb.getText() + " is "
+ cb.isChecked(), Toast.LENGTH_LONG)
.show();
}
});
} else {
chk = (CheckBox) convertView.getTag();
}
Task current = taskList.get(position);
chk.setText(current.getTaskName());
chk.setChecked(current.getStatus() == 1 ? true : false);
chk.setTag(current);
Log.d("listener", String.valueOf(current.getId()));
return convertView;
}
}
}
The main activity:
public class MainActivity extends Activity {
private Context activity;
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
entrarboton();
}
private void entrarboton() {
ImageButton accionentrar = (ImageButton) findViewById(R.id.imageButton0);
accionentrar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.android.calendar");
startActivity(LaunchIntent);
}
});
ImageButton accionentrar2 = (ImageButton) findViewById(R.id.imageButton3);
accionentrar2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,Notes.class));
}
});
ImageButton accionentrar3 = (ImageButton) findViewById(R.id.imageButton2);
accionentrar3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,ViewTask.class));
}
});
ImageButton accionentrar4 = (ImageButton) findViewById(R.id.imageButton4);
accionentrar4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,Altres.class));
}
});
AutoCompleteTextView auto = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
String[] noms = getResources() . getStringArray(R.array.noms_array);
ArrayAdapter<String> adapter;
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, noms);
auto.setThreshold(1);
auto.setAdapter(adapter);
}
}
Android Manifest:
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.dppalvaplicacio.app.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.dppalvaplicacio.app.Calendari"
android:label="#string/title_activity_calendari" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.dppalvaplicacio.app.Notes"
android:label="#string/title_activity_notes" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.dppalvaplicacio.app.ViewTask"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.dppalvaplicacio.app.Altres"
android:label="#string/title_activity_altres" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
Logcat
Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.dppalvaplicacio.app/databases/taskerManager
at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:520)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:263)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
at com.dppalvaplicacio.app.TaskerDbHelper.getAllTasks(TaskerDbHelper.java:70)
at com.dppalvaplicacio.app.ViewTask.onCreate(ViewTask.java:33)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
TaskDbHelper
public class TaskerDbHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "taskerManager";
// tasks table name
private static final String TABLE_TASKS = "tasks";
// tasks Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_TASKNAME = "taskName";
private static final String KEY_STATUS = "status";
public TaskerDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_TASKS + " ( "
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_TASKNAME
+ " TEXT, " + KEY_STATUS + " INTEGER)";
db.execSQL(sql);
db.close();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldV, int newV) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_TASKS);
// Create tables again
onCreate(db);
}
// Adding new task
public void addTask(Task task) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TASKNAME, task.getTaskName()); // task name
// status of task- can be 0 for not done and 1 for done
values.put(KEY_STATUS, task.getStatus());
// Inserting Row
db.insert(TABLE_TASKS, null, values);
db.close(); // Closing database connection
}
public List<Task> getAllTasks() {
List<Task> taskList = new ArrayList<Task>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_TASKS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Task task = new Task();
task.setId(cursor.getInt(0));
task.setTaskName(cursor.getString(1));
task.setStatus(cursor.getInt(2));
// Adding contact to list
taskList.add(task);
} while (cursor.moveToNext());
}
// return task list
return taskList;
}
public void updateTask(Task task) {
// updating row
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TASKNAME, task.getTaskName());
values.put(KEY_STATUS, task.getStatus());
db.update(TABLE_TASKS, values, KEY_ID + " = ?",new String[] {String.valueOf(task.getId())});
db.close();
}
}
The problem is in your TaskDBHelper class, and more specifically the onCreate method. This method is called automatically when you try to do work on the database, but the database is not created yet. So it first calls the onCreate method and then the method, that does work on it, in your case - getAllTasks. The problem is that you are closing your db in the onCreate method, preventing any further operations on the database within this class instance. Your method should look like this:
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_TASKS + " ( "
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_TASKNAME
+ " TEXT, " + KEY_STATUS + " INTEGER)";
db.execSQL(sql);
}