バックグラウンド
ユーザーが連絡先の画像をクリックしたときに表示されるように、アプリにアカウントを追加しました ( 「連絡先カード」セクションに表示されているように)。
今のところ、同期時に機能を必要としないため、「onPerformSync」のコードは完全に空です。後でコードを追加するかもしれません。
問題
何らかの理由で、一部のデバイス (Android 4.3 を搭載した Nexus 4 など) では、同期サービスが何もしていないにもかかわらず、非常に長い時間 (少なくとも 9 時間、場合によってはそれ以上) 起動したままになっているようです。
このようなデバイスでは、アプリがバッテリーを消耗するため、この問題を解決することが重要です。
ただし、私が読んだり聞いたりしたことによると、この機能には、何もする必要がない場合でも、syncAdapter が必要です。
コード
実際、コードは他のサンプルとほとんど同じであるため、特別なことは何もありません。現時点では同期する必要がないため、コードも大幅に削減されています。
それにもかかわらず、私はそれを書き留めます:
SyncAdapter :
public class SyncAdapter extends AbstractThreadedSyncAdapter {
public SyncAdapter (Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider,
SyncResult syncResult) {
}
}
同期サービス:
public class SyncService extends Service {
private static final Object sSyncAdapterLock = new Object();
private static SyncAdapter sSyncAdapter = null;
@Override
public void onCreate() {
synchronized (sSyncAdapterLock) {
if (sSyncAdapter == null) {
sSyncAdapter = new SyncAdapter (getApplicationContext(), true);
}
}
}
@Override
public IBinder onBind(final Intent intent) {
return sSyncAdapter.getSyncAdapterBinder();
}
}
編集: この問題に対するより多くの手がかりを与えるために、より多くのコードを表示することにしました:
マニフェスト:
<service
android:name="...SyncService"
android:exported="true" >
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/syncadapter" />
<meta-data
android:name="android.provider.CONTACTS_STRUCTURE"
android:resource="@xml/contacts" />
</service>
連絡先.xml
<ContactsSource xmlns:android="http://schemas.android.com/apk/res/android" >
<ContactsDataKind
android:detailColumn="data3"
android:icon="@drawable/app_icon"
android:mimeType="vnd.android.cursor.item/....profile"
android:summaryColumn="data2"/>
</ContactsSource>
syncadapter.xml
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="....contacts"
android:allowParallelSyncs="false"
android:contentAuthority="com.android.contacts"
android:isAlwaysSyncable="false"
android:supportsUploading="false"
android:userVisible="false" />
AuthenticatorActivity :
public class AuthenticatorActivity extends AccountAuthenticatorActivity {
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent res = new Intent();
res.putExtra(AccountManager.KEY_ACCOUNT_NAME, ...);
res.putExtra(AccountManager.KEY_ACCOUNT_TYPE, ...);
res.putExtra(AccountManager.KEY_AUTHTOKEN, ...);
final Account account = new Account(AccountGeneral.ACCOUNT_NAME, ...);
final AccountManager accountManager = AccountManager.get(this);
accountManager.addAccountExplicitly(account, null, null);
ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, false);
ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 0);
setAccountAuthenticatorResult(res.getExtras());
setResult(RESULT_OK, res);
finish();
}
}
質問
なぜ発生するのですか?
サンプルのようにすべての手順を実行しましたが、同期サービスは (おそらく) ウェイク ロックを保持し続けています (ここに書かれているように) 。
おそらく、「setSyncAutomatically」または「setIsSyncable 」を呼び出す必要がありますか? もしそうなら、syncAdapters はデフォルトで自動的に同期するように設定されているということですか? そして、どこでそれを呼び出す必要がありますか? 「confirmCredentials」機能で?
それでも、何も関係がないにもかかわらずサービスが実行され続ける理由はまだ説明されていません。同期に SyncAdapter を使用する場合、この問題に再び対処する必要があります。