什么是Google Play服务MeasurementBrokerService以及如何阻止它?

时间:2017-02-10 11:58:47

标签: android firebase google-play-services

我创建了一个侦听Firebase位置的服务。

这是一项内存使用率低的简单服务。不幸的是,我看到一个名为MeasurementBrokerService的Google Play服务加入了我的服务而没有释放内存。

与相关问题不同: "Service MeasurementBrokerService is in use" is showing in my application process

上述问题没有被接受的答案,所以请不要将此标记为重复

我没有使用firebase-appindexing。

以下是我的应用级Gradle文件:

buildscript {
    repositories {
        maven { url 'https://maven.fabric.io/public' }
    }

    dependencies {
        classpath 'io.fabric.tools:gradle:1.+'
    }    
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'

repositories {
    maven { url 'https://maven.fabric.io/public' }
}


android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    defaultConfig {
        applicationId "com.example.project.recommendedapp"
        minSdkVersion 21
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        // Enabling multidex support.
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'

    compile 'com.android.support:appcompat-v7:25.1.0'
    compile 'com.android.support:cardview-v7:25.1.0'
    compile 'com.android.support:recyclerview-v7:25.1.0'
    compile 'com.android.support:design:25.1.0'
    compile 'com.android.support:support-v4:25.1.0'
    compile 'com.github.clans:fab:1.6.4'
    compile 'com.google.android.gms:play-services-location:10.0.1'
    compile('com.crashlytics.sdk.android:crashlytics:2.6.0@aar') {
        transitive = true;
    }
    compile 'com.facebook.fresco:fresco:1.0.0'
    compile 'com.google.firebase:firebase-database:10.0.1'
    compile 'com.google.firebase:firebase-messaging:10.0.1'
    compile 'com.squareup.okhttp3:okhttp:3.5.0'

}
apply plugin: 'com.google.gms.google-services'

有人可以指导我如何阻止服务加入我的流程。

服务如下:

public class SubscriptionListenerService extends Service {

DatabaseReference userNodeSubscriptionRef;

ChildEventListener subscribedTopicsListener;

SharedPreferences sessionPref,subscribedTopicsPreference;

SharedPreferences.Editor subscribedtopicsprefeditor;

String userid;

boolean stoppedInternally = false;

SharedPreferences.OnSharedPreferenceChangeListener sessionPrefChangeListener;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    //do not need a binder over here
    return null;
}

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

    Log.d("FragmentCreate","onCreate called inside service");

    sessionPref = getSharedPreferences("SessionPref",0);

    subscribedTopicsPreference=getSharedPreferences("subscribedTopicsPreference",0);

    subscribedtopicsprefeditor=subscribedTopicsPreference.edit();

    userid = sessionPref.getString("userid",null);

    sessionPrefChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            Log.d("FragmentCreate","The shared preference changed "+key);
            stoppedInternally=true;
            sessionPref.unregisterOnSharedPreferenceChangeListener(this);
            if(userNodeSubscriptionRef!=null && subscribedTopicsListener!=null){
                userNodeSubscriptionRef.removeEventListener(subscribedTopicsListener);
            }
            stopSelf();
        }
    };

    sessionPref.registerOnSharedPreferenceChangeListener(sessionPrefChangeListener);

    subscribedTopicsListener = new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            if(!(dataSnapshot.getValue() instanceof Boolean)){
                Log.d("FragmentCreate","Please test subscriptions with a boolean value");
            }else {
                if ((Boolean) dataSnapshot.getValue()) {
                    //here we subscribe to the topic as the topic has a true value
                    Log.d("FragmentCreate", "Subscribing to topic " + dataSnapshot.getKey()+" "+this.getClass().getName());
                    subscribedtopicsprefeditor.putBoolean(dataSnapshot.getKey(), true);
                    FirebaseMessaging.getInstance().subscribeToTopic(dataSnapshot.getKey());
                } else {
                    //here we unsubscribed from the topic as the topic has a false value
                    Log.d("FragmentCreate", "Unsubscribing from topic " + dataSnapshot.getKey()+" "+this.getClass().getName());
                    subscribedtopicsprefeditor.remove(dataSnapshot.getKey());
                    FirebaseMessaging.getInstance().unsubscribeFromTopic(dataSnapshot.getKey());
                }

                subscribedtopicsprefeditor.commit();
            }
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            //either an unsubscription will trigger this, or a re-subscription after an unsubscription

            if(!(dataSnapshot.getValue() instanceof Boolean)){
                Log.d("FragmentCreate","Please test subscriptions with a boolean value");
            }else{

                if((Boolean)dataSnapshot.getValue()){
                    Log.d("FragmentCreate","Subscribing to topic "+dataSnapshot.getKey()+" "+this.getClass().getName());
                    subscribedtopicsprefeditor.putBoolean(dataSnapshot.getKey(),true);
                    FirebaseMessaging.getInstance().subscribeToTopic(dataSnapshot.getKey());
                }else{
                    Log.d("FragmentCreate","Unsubscribing from topic "+dataSnapshot.getKey()+" "+this.getClass().getName());
                    subscribedtopicsprefeditor.remove(dataSnapshot.getKey());
                    FirebaseMessaging.getInstance().unsubscribeFromTopic(dataSnapshot.getKey());
                }

                subscribedtopicsprefeditor.commit();
            }

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            //Log.d("FragmentCreate","Unubscribing from topic "+dataSnapshot.getKey());
            //FirebaseMessaging.getInstance().unsubscribeFromTopic(dataSnapshot.getKey());
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {
            //do nothing, this won't happen --- rather this isnt important
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.d("FragmentCreate","Failed to listen to subscriptions node");
        }
    };

    if(userid!=null){

        Log.d("FragmentCreate","Found user id in service "+userid);

        userNodeSubscriptionRef = FirebaseDatabase.getInstance().getReference().child("Users").child(userid).child("subscriptions");

        userNodeSubscriptionRef.addChildEventListener(subscribedTopicsListener);

        userNodeSubscriptionRef.keepSynced(true);

    }else{
        Log.d("FragmentCreate","Couldn't find user id");
        stoppedInternally=true;
        stopSelf();
    }

}

@Override
public int onStartCommand(Intent intent,int flags,int startId){
    //don't need anything done over here
    //The intent can have the following extras

    //If the intent was started by the alarm manager ..... it will contain android.intent.extra.ALARM_COUNT
    //If the intent was sent by the broadcast receiver listening for boot/update ... it will contain wakelockid
    //If it was started from within the app .... it will contain no extras in the intent

    //The following will not throw an exception if the intent does not have an wakelockid in extra
    //As per android doc... the following method releases the wakelock if any specified inside the extra and returns true
    //If no wakelockid is specified, it will return false;

    if(intent!=null){
        if(BootEventReceiver.completeWakefulIntent(intent)){
            Log.d("FragmentCreate","Wakelock released");
        }else{
            Log.d("FragmentCreate","Wakelock not acquired in the first place");
        }
    }else{
        Log.d("FragmentCreate","Intent started by regular app usage");
    }

    return START_STICKY;
}

@Override
public void onDestroy(){

    if(userNodeSubscriptionRef!=null){
        userNodeSubscriptionRef.keepSynced(false);
    }

    userNodeSubscriptionRef = null;

    subscribedTopicsListener = null;

    sessionPref = null;
    subscribedTopicsPreference = null;

    subscribedtopicsprefeditor = null;

    userid = null;

    sessionPrefChangeListener = null;

    if(stoppedInternally){
        Log.d("FragmentCreate","Service getting stopped due to no userid or due to logout or data clearance...do not restart auto.. it will launch when user logs in or signs up");
    }else{

        Log.d("FragmentCreate","Service getting killed by user explicitly from running services or by force stop ... attempt restart");

        //well basically restart the service using an alarm manager ... restart after one minute

        AlarmManager alarmManager = (AlarmManager) this.getSystemService(ALARM_SERVICE);

        Intent restartServiceIntent = new Intent(this,SubscriptionListenerService.class);
        restartServiceIntent.setPackage(this.getPackageName());

        //context , uniqueid to identify the intent , actual intent , type of pending intent
        PendingIntent pendingIntentToBeFired = PendingIntent.getService(this,1,restartServiceIntent,PendingIntent.FLAG_ONE_SHOT);

        if(Build.VERSION.SDK_INT>=23){
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+600000,pendingIntentToBeFired);
        }else{
            alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+600000,pendingIntentToBeFired);
        }


    }

    super.onDestroy();

}


}

1 个答案:

答案 0 :(得分:1)

我检查过谷歌AppMeasurement服务仍然在我的设备上运行。

我采用了以下方法:

以下内容阻止了firebase的数据收集。

https://firebase.google.com/support/guides/disable-analytics告诉我们以下方法

<meta-data android:name="firebase_analytics_collection_deactivated" android:value="true" />

仅此一项仍无法阻止appMeasurement初始化。

已解决的第二步是将以下内容添加到应用程序级别gradle文件中:

configurations {
    all*.exclude group: 'com.google.firebase', module: 'firebase-core'
}

这基本上删除了firebase分析使用的所有代码。

如果它仍然不起作用,请确保gradle不包含广泛的播放服务依赖性

例如:compile&#39; com.google.android.gms:play-services-location:10.0.1&#39;

而不是com.google.android.gms:play-services:10.0.1&#39;

最糟糕的情况,我没有对此进行测试,因为以上解决了它是:

https://developers.google.com/analytics/devguides/collection/android/v4/advanced

如果没有开发人员的许可,谷歌应该停止放置不需要的东西。希望这有助于某人