英文:
Cannot use findViewById in Service,used LayoutInflater but did not help,no value shown
问题
我开发了一个用于计步的应用程序,我希望它能够在后台运行[服务]。
在这里提到了使用服务的findViewbyId
存在问题:
https://stackoverflow.com/questions/6992748/android-findviewbyid-in-service
我尝试了这个方法,但值始终为0,我做错了什么?
这是我的MainActivity
类:
public class MainActivity extends AppCompatActivity {
private final int PHYISCAL_ACTIVITY = 0;
private Button btnStopService;
private Button btnStartService;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_DENIED) {
// 请求权限
requestPermissions(new String[]{Manifest.permission.ACTIVITY_RECOGNITION}, PHYISCAL_ACTIVITY);
}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
btnStartService = findViewById(R.id.btnStartService);
btnStopService = findViewById(R.id.btnStopService);
initButtonsOnClick();
}
private void initButtonsOnClick() {
OnClickListener listener = new OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartService:
startMyService();
break;
case R.id.btnStopService:
stopMyService();
break;
default:
break;
}
}
};
btnStartService.setOnClickListener(listener);
btnStopService.setOnClickListener(listener);
}
private void startMyService() {
Intent serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);
}
private void stopMyService() {
Intent serviceIntent = new Intent(this, MyService.class);
stopService(serviceIntent);
}
}
这是我的服务类MyService
:
public class MyService extends Service implements SensorEventListener {
private Toast toast;
private Timer timer;
private TimerTask timerTask;
private SensorManager sensorManager;
private Sensor mineSensor;
int Steps;
private TextView textView;
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.sensor == mineSensor) {
Steps = (int) sensorEvent.values[0];
textView.setText(String.valueOf(Steps));
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
private class MyTimerTask extends TimerTask {
@Override
public void run() {
showToast("Your service is still working");
}
}
private void showToast(String text) {
toast.setText(text);
toast.show();
}
private void writeToLogs(String message) {
Log.d("HelloServices", message);
}
@Override
public void onCreate() {
super.onCreate();
writeToLogs("Called onCreate() method.");
timer = new Timer();
toast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
writeToLogs("Called onStartCommand() method");
clearTimerSchedule();
initTask();
timer.scheduleAtFixedRate(timerTask, 4 * 1000, 4 * 1000);
showToast("Your service has been started");
return super.onStartCommand(intent, flags, startId);
}
private void clearTimerSchedule() {
if (timerTask != null) {
timerTask.cancel();
timer.purge();
}
}
private void initTask() {
timerTask = new MyTimerTask();
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.activity_main, null);
textView = (TextView) layout.findViewById(R.id.image);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER) != null) {
mineSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
} else {
textView.setText("No Sensor ");
}
}
@Override
public void onDestroy() {
writeToLogs("Called onDestroy() method");
clearTimerSchedule();
showToast("Your service has been stopped");
super.onDestroy();
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
请注意,我已将HTML标签"
更正为正常的引号"
。如果你有任何其他翻译或问题,请告诉我。
英文:
I developed an app to count footsteps,I wanted it to be able to work in background [service]
There is a problem with findViewbyId using services mentioned here:
https://stackoverflow.com/questions/6992748/android-findviewbyid-in-service
I tried this approach,but the value is always 0,what i did wrong?
This is mine MainActivity class:
public class MainActivity extends AppCompatActivity {
private final int PHYISCAL_ACTIVITY = 0;
private Button btnStopService;
private Button btnStartService;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_DENIED) {
//ask for permission
requestPermissions(new String[]{Manifest.permission.ACTIVITY_RECOGNITION}, PHYISCAL_ACTIVITY);
}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
btnStartService = findViewById(R.id.btnStartService);
btnStopService = findViewById(R.id.btnStopService);
initButtonsOnClick();
}
private void initButtonsOnClick() {
OnClickListener listener = new OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartService:
startMyService();
break;
case R.id.btnStopService:
stopMyService();
break;
default:
break;
}
}
};
btnStartService.setOnClickListener(listener);
btnStopService.setOnClickListener(listener);
}
private void startMyService() {
Intent serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);
}
private void stopMyService() {
Intent serviceIntent = new Intent(this, MyService.class);
stopService(serviceIntent);
}}
This is my service class:
public class MyService extends Service implements SensorEventListener {
private Toast toast;
private Timer timer;
private TimerTask timerTask;
private SensorManager sensorManager;
private Sensor mineSensor;
int Steps;
private TextView textView;
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.sensor == mineSensor) {
Steps= (int) sensorEvent.values[0];
textView.setText(String.valueOf(Steps));
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
private class MyTimerTask extends TimerTask {
@Override
public void run() {
showToast("Your service is still working");
}
}
private void showToast(String text) {
toast.setText(text);
toast.show();
}
private void writeToLogs(String message) {
Log.d("HelloServices", message);
}
@Override
public void onCreate() {
super.onCreate();
writeToLogs("Called onCreate() method.");
timer = new Timer();
toast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
writeToLogs("Called onStartCommand() methond");
clearTimerSchedule();
initTask();
timer.scheduleAtFixedRate(timerTask, 4 * 1000, 4 * 1000);
showToast("Your service has been started");
return super.onStartCommand(intent, flags, startId);
}
private void clearTimerSchedule() {
if(timerTask != null) {
timerTask.cancel();
timer.purge();
}
}
private void initTask() {
timerTask = new MyTimerTask();
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.activity_main, null);
textView = (TextView) layout.findViewById(R.id.image);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER) != null) {
mineSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
} else {
textView.setText("No Sensor ");
}
}
@Override
public void onDestroy() {
writeToLogs("Called onDestroy() method");
clearTimerSchedule();
showToast("Your service has been stopped");
super.onDestroy();
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}}
答案1
得分: 0
你需要在主活动中注册广播接收器以从服务中获取值,如下所示:
private BroadcastReceiver broadcastReceiver;
if (broadcastReceiver == null) {
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 在这里获取来自服务的值
// 从 intent 中获取值并设置到你的布局中
}
};
registerReceiver(broadcastReceiver, new IntentFilter("my_receiver"));
Intent i = new Intent(getApplicationContext(), yourservice.class);
startService(i);
}
在服务类中:
Intent i = new Intent("my_receiver");
i.putExtra("myvalues", yourvalues);
sendBroadcast(i);
这段代码用于在主活动中注册广播接收器以接收来自服务的值,并在服务类中发送广播以传递这些值。
英文:
You need to register a broadcast reciever in main activity to get value from service like this:
private BroadcastReceiver broadcastReceiver;
if(broadcastReceiver == null){
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// here you get the values from service
//get values from intent and set it to your layout
}
};
registerReceiver(broadcastReceiver,new IntentFilter("my_reciever"));
Intent i =new Intent(getApplicationContext(),yourservice.class);
startService(i);
}
In service class:
Intent i = new Intent("my_reciever");
i.putExtra("myvalues",yourvalues);
sendBroadcast(i);
答案2
得分: 0
以下是您要翻译的代码部分:
我认为一个简单的解决方案(但也许不是更好的)是创建一个单例(例如DataController),其中包含LiveData字段。
在应用程序类中创建此控制器,然后将值从服务传递并在活动中观察。
public final class DataController {
private static volatile DataController instance;
private static final Object lock = new Object();
private MutableLiveData<Integer> counter = new MutableLiveData(0);
private MutableLiveData<String> message = new MutableLiveData();
public static DataController get() {
if (instance == null) {
synchronized (lock) {
if (instance == null) {
instance = new DataController();
}
}
}
return instance;
}
public void setCounter(Integer count){
counter.postValue(count);
}
public void setMessage(String str){
message.postValue(str);
}
public MutableLiveData<Integer> getCounter() {
return counter;
}
public MutableLiveData<String> getMessage() {
return message;
}
}
英文:
I think a simple solution (but maybe not better) is to create a singleton (for example DataController) with live data field.
Create this controller inside application class, then past values from the service, and observe in the activity.
public final class DataController {
private static volatile DataController instance;
private static final Object lock = new Object();
private MutableLiveData<Integer> counter = new MutableLiveData(0);
private MutableLiveData<String> message = new MutableLiveData();
public static DataController get() {
if (instance == null) {
synchronized (lock) {
if (instance == null) {
instance = new DataController();
}
}
}
return instance;
}
public void setCounter(Integer count){
counter.postValue(count);
}
public void setMessage(String str){
message.postValue(str);
}
public MutableLiveData<Integer> getCounter() {
return counter;
}
public MutableLiveData<String> getMessage() {
return message;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论