【问题标题】:Using a service and broadcast receiver "economically" right in Android在 Android 中“经济地”使用服务和广播接收器
【发布时间】:2012-11-16 14:16:14
【问题描述】:

我制作了一个应用程序来检测我连接到哪个 wifi,并根据该应用程序在静音和非静音之间更改声音模式。不过,我想知道,我这样做的方式是否合理。

我已将其作为一项服务,因为我希望它一直在检查。在服务内部,我在 onStartCommand() 方法中注册了一个广播接收器,并在 onDestroy() 中取消注册它。它不受约束。广播接收器监听连接的变化。

我真正的问题是,这是否是一种“经济上”的好方法?还是在服务运行时使用所有电池/内存?

我的(相关)服务源代码:

import java.util.ArrayList;
import java.util.List;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.IBinder;
import android.os.Vibrator;
import android.util.Log;
import android.widget.Toast;

public class CheckService extends Service {

public static final String MY_SETTINGS = "MySettings";
private ConnectivityReceiver receiver = null;
public static boolean isRunning = false;
private WifiManager wifi;
private AudioManager audio_mngr;
private SharedPreferences settings;
private List<Network> networks;
private String SSID;


@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();
    receiver = new ConnectivityReceiver();
    wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE);
    audio_mngr = (AudioManager) getBaseContext().getSystemService(Context.AUDIO_SERVICE);
    settings = getSharedPreferences(MY_SETTINGS, 0);
    networks = getAllNetworks();
    settings.registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener(){

        public void onSharedPreferenceChanged(
                SharedPreferences sharedPreferences, String key) {
            networks = getAllNetworks();
        }
    });
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) 
{
    super.onStartCommand(intent, flags, startId);
    registerReceiver(receiver,new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
    isRunning = true;
    return START_STICKY;
}

@Override
public void onDestroy() 
{
    super.onDestroy();

    //Stop the Background thread
    isRunning = false;
    unregisterReceiver(receiver);

    //Announcement about stopping
    Toast.makeText(this, "Stopping the Demo Service", Toast.LENGTH_SHORT).show();
}

public List<Network> getAllNetworks() {
    List<Network> temp = new ArrayList<Network>();
    String[] data = settings.getString("networks", "").split(",");
    if(data.length>1)
    {
        for(int i=1; i<data.length-1; i+=2)
        {
            temp.add(new Network(data[i],data[i+1]));
        }
    }
    return temp;
}

private class ConnectivityReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
        if(null != info)
        {
            if(info.getState()==NetworkInfo.State.CONNECTED)
            {
                SSID = wifi.getConnectionInfo().getSSID();
                for(Network n : networks)
                {
                    if(n.getSSID().equals(SSID))
                    {
                        if(n.isQuiet()) setQuiet();
                        else setLoud();
                        break;
                    }
                }
            }
        }
    }
}

private void setQuiet()
{
        Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        audio_mngr .setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
        v.vibrate(300);
        makeNotification(SSID,"Vibrate mode on!",R.drawable.sound_off);
}

private void setLoud()
{
        Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        audio_mngr .setRingerMode(AudioManager.RINGER_MODE_NORMAL);
        v.vibrate(300);
        makeNotification(SSID,"Normal mode on!", R.drawable.sound_on);
}

private void makeNotification(String network, String loudness, int icon)
{
    NotificationManager notificationManager = (NotificationManager) 
              getSystemService(NOTIFICATION_SERVICE);

    CharSequence tickerText = "Mode has been changed!";
    long when = System.currentTimeMillis();

    final Notification notification = new Notification(icon, tickerText, when);

    Context context = getApplicationContext();
    CharSequence contentTitle = network;
    CharSequence contentText = loudness;
    Intent notificationIntent = new Intent(this, CheckService.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

    notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

    final int HELLO_ID = 1;

    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    notificationManager.notify(HELLO_ID, notification);

}
}

【问题讨论】:

  • 只是想说这对于一个应用来说是一个非常棒的想法。
  • 谢谢,我一测试就可以上架了!
  • 您介意分享生成的代码吗?

标签: android service broadcastreceiver


【解决方案1】:

不需要长时间运行的服务。

您可以在 AndroidManifest 中设置广播接收器,并在 onReceive(Context context, Intent intent) 方法上完成所有工作。

查看以下文档,了解如何在 AndroidManifest 中设置广播接收器 http://developer.android.com/guide/topics/manifest/receiver-element.html

【讨论】:

  • 但是如果我不提供服务,如果应用程序不活动,它会做任何事情吗?我的意思是,如果我安装它、注册一个网络、关闭应用程序,我会在活动中做任何事情吗?
  • 如果你在 Android Manifest 上注册了 BroadcastReceiver,你的接收器会在每次有连接事件时被调用。您的应用不必一直在后台“运行”以获取事件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多