Java Android-应用程序关闭时从另一个类调用方法(使用AlarmManager)
我试图使用AlarmManager从另一个类调用MainActivity类中的方法 我发现这有助于我调用该方法,但当应用程序关闭且AlarmManager仍在运行时,会出现NullPointerException错误 另一个对我有效的解决方案是在AlarmRec类中使用getBatteryLevel()。当我尝试此操作时,会出现错误-无法解析方法registerReceiver(null,android.content.IntentFilter) 我的主要活动课:Java Android-应用程序关闭时从另一个类调用方法(使用AlarmManager),java,android,Java,Android,我试图使用AlarmManager从另一个类调用MainActivity类中的方法 我发现这有助于我调用该方法,但当应用程序关闭且AlarmManager仍在运行时,会出现NullPointerException错误 另一个对我有效的解决方案是在AlarmRec类中使用getBatteryLevel()。当我尝试此操作时,会出现错误-无法解析方法registerReceiver(null,android.content.IntentFilter) 我的主要活动课: package com.ds.
package com.ds.shutdown;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.BatteryManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Calendar;
public class MainActivity extends Activity {
int userLvl;
int batteryLvl;
static MainActivity mainActivity;
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainActivity = this;
batteryLvl = getBatteryLevel();
String bat = Integer.toString(batteryLvl);
TextView textViewTwo = (TextView) findViewById(R.id.textBatteryLvl);
textViewTwo.setText("Battery level: " + bat);
userLvl = loadSavedPreferences();
TextView textView = (TextView) findViewById(R.id.textUserLvl);
textView.setText("User entry: " + Integer.toString(userLvl));
if (getIntent() != null && getIntent().getExtras() != null && getIntent().getExtras().getBoolean("CALL_METHOD", false)) {
shutdown();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void shutdown() {
Toast.makeText(this, "In shutdown method", Toast.LENGTH_SHORT).show();
batteryLvl = getBatteryLevel();
String bat = Integer.toString(batteryLvl);
TextView textViewTwo = (TextView) findViewById(R.id.textBatteryLvl);
textViewTwo.setText("Battery level: " + bat);
userLvl = loadSavedPreferences();
if (batteryLvl <= userLvl) {
try {
Process process = Runtime.getRuntime().exec(new String[]{"su", "-c", "reboot -p"});
process.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public int getBatteryLevel() {
Intent batteryIntent = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
return level;
}
//OK button onClick
public void btnPress(View v) {
EditText mEditText = (EditText) findViewById(R.id.userLvl); //Look at text box
String userLvlStr = mEditText.getText().toString(); //Take contents and set to string
if (userLvlStr.matches("")){
Toast.makeText(this, "Invalid Entry", Toast.LENGTH_SHORT).show();
return;
}
userLvl = Integer.parseInt(userLvlStr); //Convert that string to an int
saveSavedPreferences(userLvl); //Save that int
setContentView(R.layout.activity_main); //Look at main activity
TextView textView = (TextView) findViewById(R.id.textUserLvl); //Look at text view
textView.setText("User entry: " + userLvlStr); //Change text view to show user entry
batteryLvl = getBatteryLevel();
String bat = Integer.toString(batteryLvl);
TextView textViewTwo = (TextView) findViewById(R.id.textBatteryLvl);
textViewTwo.setText("Battery level: " + bat);
alarmMethod();
}
//Saves variable(s) across app close
private void saveSavedPreferences(int userLvl){
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); //Create SharedPreferences object
SharedPreferences.Editor editor= sharedPref.edit(); //Now get editor
editor.putInt("userLvl", userLvl); //Put in variable
editor.commit(); //Save variable(s)
}
//Loads variable(s) across app close
private int loadSavedPreferences() {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
userLvl = sharedPrefs.getInt("userLvl", 0);
return userLvl; //Using return since only one variable is needed
}
//Set alarm
private void alarmMethod() {
alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); //Create Alarm Manager
Intent intent = new Intent(this, AlarmRec.class); //Set intent
alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
//setRepeating() lets you specify a precise custom interval--in this case, 20 seconds
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 10, alarmIntent);
Toast.makeText(MainActivity.this, "Alarm set", Toast.LENGTH_LONG).show();
}
public void cancelAlarm(View v2) {
// If the alarm has been set, cancel it.
if (alarmMgr != null) {
alarmMgr.cancel(alarmIntent);
}
TextView textView = (TextView) findViewById(R.id.textUserLvl);
textView.setText("User entry: ");
}
public static MainActivity getInstance(){
return mainActivity;
}
}
因为当应用程序关闭时,MainActivity.getInstance()返回null 您应该在BroadcastReceiver中执行methodToCall()(如果该方法不需要很长时间),或者从那里调用服务,在那里执行methodToCall() 另一种方法是像这样修改你的接收器
Toast.makeText(context, "Calling shutdown", Toast.LENGTH_SHORT).show();
if (MainActivity.getInstance() != null) {
MainActivity.getInstance().methodToCall();
}
else {
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("CALL_METHOD", true);
context.startActivity(i);
}
调用方法extra的onCreate检查中的main活动
if (getIntent() != null && getIntent().getExtras() != null && getIntent().getExtras().getBoolean("CALL_METHOD", false)) {
methodToCall();
}
你的意思是从onReceive方法调用methodToCall()吗?应用程序会在用户定义的电池电量下关闭手机,将该方法重新写入onReceive会起作用,但由于某些原因,更新电池电量在onReceive中不起作用。我已使用getBatteryLevel()方法更新了问题中的代码。当我将代码复制到AlarmRec类中时,我得到了“无法解析方法”registerReceiver(null,android.content.IntentFilter),因为在BroadcastReceiver中,您应该像context.registerReceiver(null,android.content.IntentFilter)一样调用它。用另一个解决方案更新了我的答案。感谢您的帮助,但现在应用程序在启动时崩溃,出现错误-尝试在空对象引用上调用虚拟方法“boolean android.os.Bundle.getBoolean(java.lang.String)”。您不能这样做。当应用程序关闭时,MainActivity.getInstance()返回null。你可以在Broadcast中编写方法。我不能在BroadcastReceiver中编写方法,因为我需要获得电池电量,我不知道如何使用BroadcastReceiver。我已经对另一个答案进行了评论,为什么我的代码不能,以及为什么我不能在AlarmRec类中使用它。(您可能在评论之前就开始键入答案)。
if (getIntent() != null && getIntent().getExtras() != null && getIntent().getExtras().getBoolean("CALL_METHOD", false)) {
methodToCall();
}