即使关闭应用程序也能获取电池状态

问题描述:

嘿,我正在尝试制作一个应用程序,该应用程序可以在手机接通电源时告诉我电池何时充满电. 我提供了一项服务,并在其中使用了广播接收器来检查电池状态. 每当我将电话连接或断开电源时,我的应用就会崩溃.该服务仍在运行,并且当电池充满时我会收到通知.

Hey I am trying to make an application that tells me when the battery is full when the phone is connected to power. I made a service and used a broadcast receiver in that to check the battery status. Whenever i connect or disconnect the phone from the power, my app crashes. The service still runs and i get the notification when battery is full.

我不知道为什么该应用一次又一次崩溃. 这是我的代码

I dont know why is the app crashing again and again. Here is my code

公共类Srvc扩展服务{

public class Srvc extends Service{

@Override
public int onStartCommand(Intent intent, int flags, int startId){
    // TODO Auto-generated method stub

     final IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); 
     this.registerReceiver(this.br, ifilter);


    System.out.println("started the service");


    return super.onStartCommand(intent,flags,startId);
}



public final BroadcastReceiver br = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        System.out.println("inside on recieve");

        chckbttry(intent);

    }
};

private void chckbttry(Intent intent) {
    // TODO Auto-generated method stub

    System.out.println("inside chckbttry method");

    final int currLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
    final int maxLevel = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
    int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
    boolean isCharged = status == BatteryManager.BATTERY_STATUS_FULL;
    final int percentage = (int) Math.round((currLevel * 100.0) / maxLevel);

    if (status == BatteryManager.BATTERY_STATUS_CHARGING)
    {
         System.out.println("calling the BrdCst_strt");


     if (percentage == 100 || isCharged==true) {

         System.out.println("bttry fully chrged");
         Intent i = new Intent(getBaseContext(),PlayMus.class); //call another activity
         i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         i.putExtra("msg", "Battery fully charged");
         getApplication().startActivity(i);
     }
    else
     {
        System.out.println("not yet charged");
        Intent i = new Intent(getBaseContext(), Test.class);
         i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         i.putExtra("msg", "Battery not fully charged");
         getApplication().startActivity(i);


    } 
    }

    if (status == BatteryManager.BATTERY_STATUS_DISCHARGING)
    {
        System.out.println("unregistering the service");
        unregisterReceiver(br);
    }

} 

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    System.out.println("service stopped");
    unregisterReceiver(br);
    super.onDestroy();

}

}

请帮助我.

谢谢.

像电池电量之类的系统消息将作为广播通过整个系统发送.您可以使用所谓的 BroadcastReceiver 来接收它们.

System messages like the battery level are sent as a Broadcast through the whole system. You can receive them with a so called BroadcastReceiver.

活动具有用户界面,但您需要使用 服务 .它们旨在在您的应用程序不可见时在后台进行更长的工作.您的应用必须至少启动一次,才能从 Activity 中启动此 Service . 为您提供一些其他信息: 还有 AsyncTasks .它们旨在在您的应用可见和正常工作时用作东西(例如,将数据从Internet加载到 ListView 或其他内容中).您必须执行任务",因为如果不这样做,您的UI将会冻结.在不使用任务"的情况下编写的几乎所有程序都将在UI线程中执行.如果UI线程忙,则用户将无法执行任何操作.

While Activities have an UI, you need to use a Service. They are meant to be used for doing longer work in the background while your App is not visible. Your App has to be started at least once to start this Service out of an Activity. Some additional information for you: There are also AsyncTasks. Those are meant to be used for stuff while your App is visible and working (like loading data from the Internet into a ListView or something). You have to Tasks, because your UI will freeze if you do not do so. Almost Everything you program without using Tasks, will be executed in the UI Thread. If the UI Thread gets busy, the user will not be able to do anything.

现在这里有一些代码:

Now here some code:

MainActivity.java

MainActivity.java

public class MainActivity extends ActionBarActivity {

    private MyService service;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (service == null) {
            // start service
            Intent i = new Intent(this, MyService.class);
            startService(i);
        }
        // finish our activity. It will be started when our battery is full.
        finish();
    }
}

MyService.java

MyService.java

public class MyService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService", "onStartCommand");
        // do not receive all available system information (it is a filter!)
        final IntentFilter battChangeFilter = new IntentFilter(
                Intent.ACTION_BATTERY_CHANGED);
        // register our receiver
        this.registerReceiver(this.batteryChangeReceiver, battChangeFilter);
        return super.onStartCommand(intent, flags, startId);
    }

    private final BroadcastReceiver batteryChangeReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(final Context context, final Intent intent) {
            checkBatteryLevel(intent);
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        // There are Bound an Unbound Services - you should read something about
        // that. This one is an Unbounded Service.
        return null;
    }

    private void checkBatteryLevel(Intent batteryChangeIntent) {
        // some calculations
        final int currLevel = batteryChangeIntent.getIntExtra(
                BatteryManager.EXTRA_LEVEL, -1);
        final int maxLevel = batteryChangeIntent.getIntExtra(
                BatteryManager.EXTRA_SCALE, -1);
        final int percentage = (int) Math.round((currLevel * 100.0) / maxLevel);

        Log.d("MySerive", "current battery level: " + percentage);

        // full battery
        if (percentage == 100) {
            Log.d("MySerive", "battery fully loaded");
            Intent intent = new Intent(getBaseContext(), SecondActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            getApplication().startActivity(intent);
        }
        // do not forget to unregister
        unregisterReceiver(batteryChangeReceiver);
    }

}

Manifest.xml:您需要为服务提供一个条目-就像一个活动一样.

Manifest.xml: You need an entry for your Serivice - just like for an Activity.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.mybatteryservice"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.mybatteryservice.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.example.mybatteryservice.SecondActivity" >
        </activity>
        <service android:name="com.example.mybatteryservice.MyService" >
        </service>
    </application>

</manifest>

如果您还有其他问题,请告诉我!

Please let me know if you have any more questions!

最诚挚的问候 文森特