Hi i'm a beginner in android app development.
I need help making my app. so my app is a simple Timer with progress bar which works fine.
Now i need to make that "progress bar's" to draw over other apps even if the app is minimized or closed until the timer expires.
So for this I tried many things in many ways like i used Window Manager and other things in a service class, i even separated progress bar into different layout.
help me with code. the following contains code which works fine within app.
1)Main Activity.java
import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private long timeCountInMilliSeconds = 1 * 60000;
private enum TimerStatus {
STARTED,
STOPPED
}
private TimerStatus timerStatus = TimerStatus.STOPPED;
private ProgressBar progressBar;
private ProgressBar progressBar1;
private EditText editTextMinute;
private TextView textViewTime;
private ImageView imageViewReset;
private ImageView imageViewStartStop;
private CountDownTimer countDownTimer;
private ObjectAnimator smoothAnimation;
private ObjectAnimator smoothAnimation1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// method call to initialize the views
initViews();
// method call to initialize the listeners
initListeners();
}
/**
* method to initialize the views
*/
private void initViews() {
progressBar = findViewById(R.id.progress_bar);
progressBar1 = findViewById(R.id.progress_bar1);
editTextMinute = findViewById(R.id.editTextMinute);
textViewTime = findViewById(R.id.textViewTime);
imageViewReset = findViewById(R.id.imageViewReset);
imageViewStartStop = findViewById(R.id.imageViewStartStop);
}
/**
* method to initialize the click listeners
*/
private void initListeners() {
imageViewReset.setOnClickListener(this);
imageViewStartStop.setOnClickListener(this);
}
/**
* implemented method to listen clicks
*
* #param view
*/
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.imageViewReset:
reset();
break;
case R.id.imageViewStartStop:
startStop();
break;
}
}
/**
* method to reset count down timer
*/
private void reset() {
stopCountDownTimer();
startCountDownTimer();
}
/**
* method to start and stop count down timer
*/
private void startStop() {
if (timerStatus == TimerStatus.STOPPED) {
// call to initialize the timer values
setTimerValues();
// call to initialize the progress bar values
setProgressBarValues();
// showing the reset icon
imageViewReset.setVisibility(View.VISIBLE);
// changing play icon to stop icon
imageViewStartStop.setImageResource(R.drawable.icon_stop);
// making edit text not editable
editTextMinute.setEnabled(false);
// changing the timer status to started
timerStatus = TimerStatus.STARTED;
// call to start the count down timer
startCountDownTimer();
} else {
// hiding the reset icon
imageViewReset.setVisibility(View.GONE);
// changing stop icon to start icon
imageViewStartStop.setImageResource(R.drawable.icon_start);
// making edit text editable
editTextMinute.setEnabled(true);
// changing the timer status to stopped
timerStatus = TimerStatus.STOPPED;
stopCountDownTimer();
}
}
/**
* method to initialize the values for count down timer
*/
private void setTimerValues() {
int time = 0;
if (!editTextMinute.getText().toString().isEmpty()) {
// fetching value from edit text and type cast to integer
time = Integer.parseInt(editTextMinute.getText().toString().trim());
} else {
// toast message to fill edit text
Toast.makeText(getApplicationContext(), getString(R.string.message_minutes), Toast.LENGTH_LONG).show();
}
// assigning values after converting to milliseconds
timeCountInMilliSeconds = time * 1000;
}
/**
* method to start count down timer
*/
private void startCountDownTimer() {
//left side Progress Bar
smoothAnimation = ObjectAnimator.ofInt(progressBar, "progress", progressBar.getProgress(), progressBar.getMax());
smoothAnimation.setDuration(5);
smoothAnimation.setInterpolator(new AccelerateInterpolator());
//right side Progress Bar
smoothAnimation1 = ObjectAnimator.ofInt(progressBar, "progress", progressBar1.getProgress(), progressBar1.getMax());
smoothAnimation1.setDuration(5);
smoothAnimation1.setInterpolator(new AccelerateInterpolator());
countDownTimer = new CountDownTimer(timeCountInMilliSeconds, 10) {
#Override
public void onTick(long millisUntilFinished) {
Log.d("TAG", "ON Tick Called "+millisUntilFinished);
textViewTime.setText(hmsTimeFormatter(millisUntilFinished+1000));
progressBar.setProgress((int) (timeCountInMilliSeconds / 10 - millisUntilFinished / 10));
progressBar1.setProgress((int) (timeCountInMilliSeconds / 10 - millisUntilFinished / 10));
}
#Override
public void onFinish() {
textViewTime.setText(hmsTimeFormatter(timeCountInMilliSeconds));
// call to initialize the progress bar values
setProgressBarValues();
// hiding the reset icon
imageViewReset.setVisibility(View.GONE);
// changing stop icon to start icon
imageViewStartStop.setImageResource(R.drawable.icon_start);
// making edit text editable
editTextMinute.setEnabled(true);
// changing the timer status to stopped
timerStatus = TimerStatus.STOPPED;
smoothAnimation.end();
}
}.start();
smoothAnimation.start();
countDownTimer.start();
}
/**
* method to stop count down timer
*/
private void stopCountDownTimer() {
countDownTimer.cancel();
}
/**
* method to set circular progress bar values
*/
private void setProgressBarValues() {
progressBar.setMax((int) (timeCountInMilliSeconds / 10));
progressBar.setProgress((int) (timeCountInMilliSeconds / 10));
progressBar1.setMax((int) (timeCountInMilliSeconds / 10));
progressBar1.setProgress((int) (timeCountInMilliSeconds / 10));
}
/**
* method to convert millisecond to time format
*
* #param milliSeconds
* #return HH:mm:ss time formatted string
*/
private String hmsTimeFormatter(long milliSeconds) {
String hms = String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(milliSeconds),
TimeUnit.MILLISECONDS.toMinutes(milliSeconds) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milliSeconds)),
TimeUnit.MILLISECONDS.toSeconds(milliSeconds) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliSeconds)));
return hms;
}
}
2)activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorBackground">
<ProgressBar
android:id="#+id/progress_bar"
android:animationResolution="6000"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:max="100"
android:progress="0"
android:progressDrawable="#drawable/progressbar_vertical" />
<ProgressBar
android:id="#+id/progress_bar1"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:animationResolution="6000"
android:max="100"
android:progress="0"
android:progressDrawable="#drawable/progressbar_vertical" />
<EditText
android:id="#+id/editTextMinute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textViewTime"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:gravity="center"
android:hint="#string/hint_minute"
android:inputType="number"
android:maxLength="15"
android:maxLines="1"
android:minEms="5"
android:text=""
android:textColor="#color/colorYellow"
android:textColorHint="#color/colorYellow" />
<TextView
android:id="#+id/textViewTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="00:01:00"
android:textColor="#color/colorYellow"
android:textSize="40sp" />
<ImageView
android:id="#+id/imageViewStartStop"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_below="#+id/textViewTime"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:src="#drawable/icon_start" />
<ImageView
android:id="#+id/imageViewReset"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_below="#+id/imageViewStartStop"
android:layout_centerInParent="true"
android:layout_marginTop="30dp"
android:src="#drawable/icon_reset"
tools:visibility="visible"
android:visibility="gone" />
</RelativeLayout>
The following contains some screenshots please take a look.
Timer pic
Timer pic 2
The Above code works
Now i added service code that i am trying
-ProgressBarService.java (In this i don't know which code should i move from main activity to this and HOW??)
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import static android.view.Gravity.END;
public class ProgressBarService extends Service {
private WindowManager mWindowManager;
private View mProgressView;
public ProgressBarService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#SuppressLint("InflateParams")
#Override
public void onCreate() {
super.onCreate();
mProgressView = LayoutInflater.from(this).inflate(R.layout.progressbar_view, null);
final WindowManager.LayoutParams paramsProgress = getLayoutParams();
paramsProgress.gravity=END;
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
if (mWindowManager != null) {
mWindowManager.addView(mProgressView, paramsProgress);
}
}
private WindowManager.LayoutParams getLayoutParams() {
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
return params;
}
#Override
public void onDestroy() {
super.onDestroy();
if (mProgressView != null) mWindowManager.removeView(mProgressView);
}
}
-progressbar_view (seperated from activity_main)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="#+id/progress_bar"
android:animationResolution="6000"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:max="100"
android:progress="100"
android:progressDrawable="#drawable/progressbar_vertical" />
<!-- <ProgressBar
android:id="#+id/progress_bar1"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:animationResolution="6000"
android:max="100"
android:progress="100"
android:progressDrawable="#drawable/progressbar_vertical" />-->
</RelativeLayout>
Related
This question already has answers here:
android.content.res.Resources$NotFoundException: String resource ID #0x0
(8 answers)
Closed 5 years ago.
I am trying to make an app to generate random numbers based on range specified by the user.
I had some issue before where when trying to switch to that fragment, it would crash the app, but that was solved because the onClickListener was at the wrong place.
Logcat settings is Verbose and No Filters. When the app crashes nothing comes up, so I am very confused as to why the app is crashing.
This is my first time actually building an app.
Below is the respective Fragment.java file:
package com.lava.ldc.randomnumbersapp;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Random;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link RandomNumberGeneratorFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link RandomNumberGeneratorFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class RandomNumberGeneratorFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public RandomNumberGeneratorFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment RandomNumberGeneratorFragment.
*/
// TODO: Rename and change types and number of parameters
public static RandomNumberGeneratorFragment newInstance(String param1, String param2) {
RandomNumberGeneratorFragment fragment = new RandomNumberGeneratorFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
EditText start;
EditText end;
Button btnGenerate;
TextView randNum;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = (RelativeLayout) inflater.inflate(R.layout.fragment_random_number_generator, container, false);
bindView(view);
btnGenerate = (Button) view.findViewById(R.id.buttonGen);
btnGenerate.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
int min = Integer.parseInt(start.getText().toString());
int max = Integer.parseInt(end.getText().toString());
Random random = new Random();
if(min>max){
Toast toast = new Toast(getActivity().getApplicationContext());
Toast.makeText(getActivity().getApplicationContext(), "The minimum range value you entered is larger then the maximum range value!", Toast.LENGTH_SHORT).show();
}
double randomMultiplier = random.nextDouble();
long range = (long)max - (long)min + 1;
int randomNumber = (int)((long)(range * randomMultiplier) + min);
randNum.setText(randomNumber);
}
});
//Initiated Broadcast receiver
return view;
}
private void bindView(View view){
start = (EditText) view.findViewById(R.id.start);
end = (EditText) view.findViewById(R.id.end);
randNum = (TextView) view.findViewById(R.id.randomNumber);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}}
Below is the Fragment.xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lava.ldc.randomnumbersapp.RandomNumberGeneratorFragment">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.5"
android:background="#drawable/rnbg" />
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="#+id/randomNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="#000000"
android:textSize="50sp"
android:textStyle="bold"
android:layout_marginBottom="85dp"
android:layout_above="#+id/buttonGen"
android:layout_centerHorizontal="true" />
<Button
android:id="#+id/buttonGen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="82dp"
android:elevation="24dp"
android:text="Generate"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
<EditText
android:id="#+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Enter lower range value"
android:inputType="number"
android:layout_above="#+id/end"
android:layout_centerHorizontal="true"
android:layout_marginBottom="30dp" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="14dp"
android:text="ENTER RANGE"
android:textAlignment="center"
android:textAllCaps="false"
android:textColor="#000000"
android:textSize="36sp"
android:textStyle="bold" />
<EditText
android:id="#+id/end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Enter highest range value"
android:inputType="number"
android:layout_marginBottom="76dp"
android:layout_above="#+id/randomNumber"
android:layout_alignLeft="#+id/start"
android:layout_alignStart="#+id/start" />
</RelativeLayout>
I just don't know where I am going wrong.
All help appreciated.
It's possible that randNum.setText(randomNumber); is the cause of the problem.
It is attempting to use randomNumber as a resource id.
See the Android Framework docs for TextView.setText(int) as a reference.
What you need to do is convert randomNumber to a string. For example:
randNum.setText(Integer.toString(randomNumber));
I use this code
TextView.animate().setDuration(0).scaleX(scale).scaleY(scale).start();
When scale value increase to some point, it make TextView disappear. I dont know why, and how to prevent it?
[Edit] Attach my test code
[test_text_scale.xml] It is Layout xml file for TestTextScale.java
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:orientation="vertical">
<TextView
android:id="#+id/tv_test_scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Test" />
<Button
android:id="#+id/bt_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toEndOf="#+id/bt_down"
android:layout_toRightOf="#+id/bt_down"
android:text="Up" />
<Button
android:id="#+id/bt_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="Down" />
</RelativeLayout>
[TestTextScale.java]
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class TestTextScale extends AppCompatActivity {
// View
private TextView mTvTestZoom;
private Button mBtUp, mBtDown;
// Model
private int mCurrentScale = 1;
// OnClick listener
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_up : {
upScale();
setText();
} break;
case R.id.bt_down : {
downScale();
setText();
} break;
}
}
};
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_text_scale);
initView();
initEvent();
}
private void initView() {
mTvTestZoom = (TextView) findViewById(R.id.tv_test_scale);
mBtUp = (Button) findViewById(R.id.bt_up);
mBtDown = (Button) findViewById(R.id.bt_down);
}
private void initEvent() {
mBtDown.setOnClickListener(mOnClickListener);
mBtUp.setOnClickListener(mOnClickListener);
}
private void upScale() {
mCurrentScale += 1;
mTvTestZoom.animate().setDuration(0).scaleX(mCurrentScale).scaleY(mCurrentScale).start();
}
private void downScale() {
mCurrentScale -= 1;
mTvTestZoom.animate().setDuration(0).scaleX(mCurrentScale).scaleY(mCurrentScale).start();
}
private void setText() {
mTvTestZoom.setText(mCurrentScale + "");
}
}
This may happen because the textview exceeds the layout bounds of its parent. To overcome this, simple put android:clipChildren="false" in the xml description of the immediate parent of the textview. You may also need to do it for their parents too.
EDIT:
Upon testing the code myself, I found that the textview did disappear with following log message:
E/OpenGLRenderer: Font size too large to fit in cache. width, height = 635, 1028
This is due to a possible issue in the Android Hardware acceleration modules. One of the ways to avoid this is:
mTvTestZoom.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
This works well and the textView does not disappear after a certain size but, since it disables hardware acceleration for the specific textview, it may lose antialiasing.
I've been learning some java for android by reading and trying codes, and whenever I start the application on android it crashes. In the LogCat, this shows:
08-09 16:13:24.033: E/AndroidRuntime(839): ... 11 more
Here is my activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="Brews: " />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="None"
android:gravity="end"
android:textSize="20sp"
android:id="#+id/brew_count_label" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:padding="10dip">
<Button
android:id="#+id/brew_time_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-"
android:textSize="40sp" />
<TextView
android:id="#+id/brew_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0:00"
android:textSize="40sp"
android:padding="10dip" />
<Button
android:id="#+id/brew_time_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+"
android:textSize="40sp" />
</LinearLayout>
<Button
android:id="#+id/brew_start"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Start" />
</LinearLayout>
And here is my MainActivity.java:
package com.example.basketball;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity implements OnClickListener {
/** Properties **/
protected Button brewAddTime;
protected Button brewDecreaseTime;
protected Button startBrew;
protected TextView brewCountLabel;
protected TextView brewTimeLabel;
protected int brewTime = 3;
protected CountDownTimer brewCountDownTimer;
protected int brewCount = 0;
protected boolean isBrewing = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
// Connect interface elements to properties
brewAddTime = (Button) findViewById(R.id.brew_time_up);
brewDecreaseTime = (Button) findViewById(R.id.brew_time_down);
startBrew = (Button) findViewById(R.id.brew_start);
brewCountLabel = (TextView) findViewById(R.id.brew_count_label);
brewTimeLabel = (TextView) findViewById(R.id.brew_time);
// Setup ClickListeners
brewAddTime.setOnClickListener(this);
brewDecreaseTime.setOnClickListener(this);
startBrew.setOnClickListener(this);
// Set the initial brew values
setBrewCount(0);
setBrewTime(3);
}
/** Methods **/
/**
* Set an absolute value for the number of minutes to brew. Has no effect if a brew
* is currently running.
* #param minutes The number of minutes to brew.
*/
public void setBrewTime(int minutes) {
if(isBrewing)
return;
brewTime = minutes;
if(brewTime < 1)
brewTime = 1;
brewTimeLabel.setText(String.valueOf(brewTime) + "m");
}
/**
* Set the number of brews that have been made, and update the interface.
* #param count The new number of brews
*/
public void setBrewCount(int count) {
brewCount = count;
brewCountLabel.setText(String.valueOf(brewCount));
}
/**
* Start the brew timer
*/
public void startBrew() {
// Create a new CountDownTimer to track the brew time
brewCountDownTimer = new CountDownTimer(brewTime * 60 * 1000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
brewTimeLabel.setText(String.valueOf(millisUntilFinished / 1000) + "s");
}
#Override
public void onFinish() {
isBrewing = false;
setBrewCount(brewCount + 1);
brewTimeLabel.setText("Brew Up!");
startBrew.setText("Start");
}
};
brewCountDownTimer.start();
startBrew.setText("Stop");
isBrewing = true;
}
/**
* Stop the brew timer
*/
public void stopBrew() {
if(brewCountDownTimer != null)
brewCountDownTimer.cancel();
isBrewing = false;
startBrew.setText("Start");
}
/** Interface Implementations **/
/* (non-Javadoc)
* #see android.view.View.OnClickListener#onClick(android.view.View)
*/
public void onClick(View v) {
if(v == brewAddTime)
setBrewTime(brewTime + 1);
else if(v == brewDecreaseTime)
setBrewTime(brewTime -1);
else if(v == startBrew) {
if(isBrewing)
stopBrew();
else
startBrew();
}
}
}
Anyone knows how to fix this error?
Please help.
Please uncomment setContentView(R.layout.main); and change that line to setContentView(R.layout.activity_main); in
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
I'm new to android development and I'm having some debugging issues. I'm learning from a youtube channel called "TheNewBoston" and have run into issues on lesson 10. I didn't use the same src package as the guy in the tutorial as I couldn't find it so I'm wondering if this has caused the problem.
the add and sub buttons both have the same 'Multiple markers at this line - button can not be resolved by type' errors within the OnCreate method.
Java:
package com.example.thenewboston.sam;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.example.thenewboston.sam.util.SystemUiHider;
public class FullscreenActivity extends Activity {
/**
* Whether or not the system UI should be auto-hidden after
* {#link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
*/
int counter;
Button add, sub;
TextView Display;
private static final boolean AUTO_HIDE = true;
/**
* If {#link #AUTO_HIDE} is set, the number of milliseconds to wait after
* user interaction before hiding the system UI.
*/
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
/**
* If set, will toggle the system UI visibility upon interaction. Otherwise,
* will show the system UI visibility upon interaction.
*/
private static final boolean TOGGLE_ON_CLICK = true;
/**
* The flags to pass to {#link SystemUiHider#getInstance}.
*/
private static final int HIDER_FLAGS = SystemUiHider.FLAG_HIDE_NAVIGATION;
/**
* The instance of the {#link SystemUiHider} for this activity.
*/
private SystemUiHider mSystemUiHider;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen);
counter = 0;
add = (button) findViewById(R.id.bAdd);
sub = (button) findViewbyId(R.id.bSub);
Display = (TextView) findViewById(R.id.tvDisplay);
add.SetOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
counter++;
Display.setText("your total is " + counter);
}
});
sub.SetOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
counter--;
}
});
final View controlsView = findViewById(R.id.fullscreen_content_controls);
final View contentView = findViewById(R.id.fullscreen_content);
// Set up an instance of SystemUiHider to control the system UI for
// this activity.
mSystemUiHider = SystemUiHider.getInstance(this, contentView,
HIDER_FLAGS);
mSystemUiHider.setup();
mSystemUiHider
.setOnVisibilityChangeListener(new SystemUiHider.OnVisibilityChangeListener() {
// Cached values.
int mControlsHeight;
int mShortAnimTime;
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!--
The primary full-screen view. This can be replaced with whatever view
is needed to present your content, e.g. VideoView, SurfaceView,
TextureView, etc.
-->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Your total is 0"
android:textSize="45sp"
android:textStyle="bold"
android:layout_gravity="center"
android:gravity="center"
android:id="#+id/tvDisplay"
/>
<Button
android:layout_width="250sp"
android:layout_height="wrap_content"
android:text="Add one"
android:layout_gravity="center"
android:textSize="20sp"
android:id="#+id/bAdd"
></Button>
<Button
android:layout_width="250sp"
android:layout_height="wrap_content"
android:text="Subtract one"
android:layout_gravity="center"
android:textSize="20sp"
android:id="#+id/bSub"
></Button>
</LinearLayout>
<!--
This FrameLayout insets its children based on system windows using
android:fitsSystemWindows.
-->
add.SetOnClickListener
the s of SetOnClickListener has to be lowercase.
Also the cast:
(button)
is wrong, as mention on the comment box. It should be Button
add = (button)
Button should have the first character Uppercase.
Do the following changes
add = (Button) findViewById(R.id.bAdd);
sub = (Button) findViewbyId(R.id.bSub);
instead of
add = (button) findViewById(R.id.bAdd);
sub = (button) findViewbyId(R.id.bSub);
and also in SetOnClickListener S must be s( Small )
:) Enjoy Coding...
I am creating a soundboard Android application in order to gain more of an understanding of what goes on under the hood of an application.
Currently have three seekbars in an activity called ChangeSounds. They control volume, panning and playback speed. I have coded a java file called SoundManager that handles these parameters. I am at the stage of linking the functionality of the soundManager to the ChangeSounds activity but I don't know how I should go about doing it. Should I use an intent? Or should I use a broadcast receiver? Any help would be greatly appreciated.
ChangeSounds.java
package com.example.beatpadmaker;
// Importing necessary libraries
import android.app.Activity;
import android.os.Bundle;
public class ChangeSounds extends Activity {
// sets the layout to changesounds
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.changesounds);
}
changesounds.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/metalbackground"
android:orientation="vertical" >
<!-- Creates the settings text -->
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/titlesettings"
android:textColor="#FFFFFF"
android:textSize="30sp" >
</TextView>
<!-- Creates the volume text -->
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/volumebar"
android:textColor="#FFFFFF" >
</TextView>
<!-- Creates the seekbar for volume -->
<SeekBar
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:id="#+id/VolBar1"
android:max="100"
android:progress="100">
</SeekBar>
<!-- Creates the balance text -->
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/balance"
android:textColor="#FFFFFF" >
</TextView>
<!-- Creates the seekbar for audio balance -->
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="200"
android:id="#+id/BalBar"
android:progress="100">
</SeekBar>
<!-- Creates the speed text -->
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/speed"
android:textColor="#FFFFFF" >
</TextView>
<!-- Creates the seekbar for speed -->
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/SpeedBar"
android:max="200"
android:progress="100">
</SeekBar>
</LinearLayout>
SoundManager.java
package com.example.beatpadmaker;
//Importing necessary libraries
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
public class SoundManager {
//Initialising all variables
private Context pContext;
private SoundPool sndPool;
private float rate = 1.0f;
private float masterVolume = 1.0f;
private float leftVolume = 1.0f;
private float rightVolume = 1.0f;
private float balance = 0.5f;
// Constructor that is used to setup the audio manager and store the application context
public SoundManager(Context appContext)
{
sndPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 100);
pContext = appContext;
}
// Load up a sound and return the id
public int load(int sound_id)
{
return sndPool.load(pContext, sound_id, 1);
}
// Play a sound
public void play(int sound_id)
{
sndPool.play(sound_id, leftVolume, rightVolume, 1, 0, rate);
}
// Set volume values based on existing volume value
public void setVolume(float vol)
{
masterVolume = vol;
if(balance < 1.0f)
{
leftVolume = masterVolume;
rightVolume = masterVolume * balance;
}
else
{
rightVolume = masterVolume;
leftVolume = masterVolume * ( 2.0f - balance );
}
}
// Determine the speed of audio playback
public void setSpeed(float speed)
{
rate = speed;
// Speed of zero is invalid
if(rate < 0.01f)
rate = 0.01f;
// Speed has a maximum of 2.0
if(rate > 2.0f)
rate = 2.0f;
}
// Recalculate volume levels
public void setBalance(float balVal)
{
balance = balVal;
setVolume(masterVolume);
}
// Releases the soundpool's contents
public void unloadAll()
{
sndPool.release();
}
}
MainMenu.java
package com.example.beatpadmaker;
//Importing necessary libraries
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class MainMenu extends Activity {
//Initializing all variables as well as a tag string for testing my life cycle in logcat
private static final String TAG= MainMenu.class.getSimpleName();
SoundManager snd;
int sound1, sound2, sound3, sound4, sound5, sound6, sound7, sound8, sound9, sound10, sound11, sound12;
OnSeekBarChangeListener barChange;
OnClickListener buttonClick;
//Creating the layout
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
Log.d(TAG, "onCreate() called!");
// Create an instance of our sound manger
snd = new SoundManager(getApplicationContext());
// Set volume rocker mode to media volume
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
// Load the samples from res/raw as oggs
sound1 = snd.load(R.raw.sound1);
sound2 = snd.load(R.raw.sound2);
sound3 = snd.load(R.raw.sound3);
sound4 = snd.load(R.raw.sound4);
sound5 = snd.load(R.raw.sound5);
sound6 = snd.load(R.raw.sound6);
sound7 = snd.load(R.raw.sound7);
sound8 = snd.load(R.raw.sound8);
sound9 = snd.load(R.raw.sound9);
sound10 = snd.load(R.raw.sound10);
sound11 = snd.load(R.raw.sound11);
sound12 = snd.load(R.raw.sound12);
// Create a seek bar handler
barChange = new OnSeekBarChangeListener()
{
#Override
public void onStopTrackingTouch(SeekBar seekBar)
{
}
#Override
public void onStartTrackingTouch(SeekBar seekBar)
{
}
//Creating the three cases for the different seekbars to get the progress of volume, balance and speed
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
switch (seekBar.getId())
{
case R.id.VolBar1:
snd.setVolume((float)progress/100.0f);
break;
case R.id.BalBar:
snd.setBalance((float)progress/100.0f);
break;
case R.id.SpeedBar:
snd.setSpeed((float)progress/100.0f);
break;
}
}
};
}
// Button listener assigned in XML layout
public void clickHandler(View v)
{
int id = v.getId();
// Use the button id to determine which sample should be played
switch (id)
{
case R.id.button1:
snd.play(sound1);
break;
case R.id.button2:
snd.play(sound2);
break;
case R.id.button3:
snd.play(sound3);
break;
case R.id.button4:
snd.play(sound4);
break;
case R.id.button5:
snd.play(sound5);
break;
case R.id.button6:
snd.play(sound6);
break;
case R.id.button7:
snd.play(sound7);
break;
case R.id.button8:
snd.play(sound8);
break;
case R.id.button9:
snd.play(sound9);
break;
case R.id.button10:
snd.play(sound10);
break;
case R.id.button11:
snd.play(sound11);
break;
case R.id.button12:
snd.play(sound12);
break;
}
}
in onCreate(), get a reference to each seekbar using
SeekBar bar = (SeekBar) findViewById(R.id.volume);
Then set the listener on it.
bar.setOnSeekBarChangeListener(barChangeListener);
Make sure if you do this way you define the listener.
private OnSeekBarChangeListener barChangeListener = new OnSeekBarChangeListener() {
// implement abstract methods
}