我是Android新手,我正在尝试写一个SyncAdapter- 是否有可能限制SyncAdapter只在网络是WiFi(而不是3G等)时执行同步?
我通过SyncAdapter onPerformSync发送几个改装调用,我试图通过try/catch sleep语句发送来调节http调用.但是,这会阻止UI,并且只有在完成所有调用后才会响应.
什么是在onPerformSync中在后台调节网络调用(使用睡眠定时器)而不阻止UI的更好方法?
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
String baseUrl = BuildConfig.API_BASE_URL;
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
service = retrofit.create(HTTPService.class);
Call<RetroFitModel> RetroFitModelCall = service.getRetroFit(apiKey, sortOrder);
RetroFitModelCall.enqueue(new Callback<RetroFitModel>() {
@Override
public void onResponse(Response<RetroFitModel> response) {
if (!response.isSuccess()) {
} else {
List<RetroFitResult> retrofitResultList = response.body().getResults();
Utility.storeList(getContext(), retrofitResultList);
for (final RetroFitResult result : retrofitResultList) {
RetroFitReview(result.getId(), service);
try {
// Sleep for SLEEP_TIME before running RetroFitReports & RetroFitTime
Thread.sleep(SLEEP_TIME); …Run Code Online (Sandbox Code Playgroud) 我和EventBusGreenrobot 有问题.
我试图从我的同步适配器的后台服务发布事件,并在片段中捕获它以更新UI.
问题是当我尝试从同步适配器发布事件时,我在调试日志中得到以下内容:
No subscribers registered for event class olexiimuraviov.ua.simplerssreader.event.UpdateUIEvent No subscribers registered for event class org.greenrobot.eventbus.NoSubscriberEvent
我在其中注册片段onResume并取消注册onPause
@Override
public void onResume() {
super.onResume();
EventBus.getDefault().register(this);
if (mDebug) Log.d(LOG_TAG, EventBus.getDefault().isRegistered(this) + "");
}
@Override
public void onPause() {
super.onPause();
EventBus.getDefault().unregister(this);
}
Run Code Online (Sandbox Code Playgroud)
onResume中的日志语句显示片段已成功注册.
这是onEvent方法:
@Subscribe
public void onEvent(UpdateUIEvent event) {
if (mSwipeRefreshLayout.isRefreshing())
mSwipeRefreshLayout.setRefreshing(false);
}
Run Code Online (Sandbox Code Playgroud)
我试图用Background threadmode调用onEvent方法,但它没有帮助.
在此之后,我试图使用处理程序发布事件,但eventbus仍然找不到任何注册订阅者的事件.
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new UpdateUIEvent());
}
});
Run Code Online (Sandbox Code Playgroud)
这是我的onPerform同步适配器方法:
@Override
public void onPerformSync(Account account, …Run Code Online (Sandbox Code Playgroud) android event-bus android-syncadapter android-fragments greenrobot-eventbus
我使用SyncAdapter时遇到问题.关于它的最奇怪的事情是它早先工作,但现在同步只有在我手动调用时才有效.
它也不适用于模拟器(API 24)
这是我的同步适配器代码:
public class SmogAppSyncAdapter extends AbstractThreadedSyncAdapter {
private static final String LOG_TAG = SmogAppSyncAdapter.class.getSimpleName();
public static final int SYNC_INTERVAL = 60; // 60 * 60 = 1h to the nearest 20min.
public static final int SYNC_FLEXTIME = SYNC_INTERVAL / 3;
public static final int POLLUTION_DISTANCE = 10000; //preferred distance between prefs location and nearest measurement point
private static final int POLLUTION_NOTIFICATION_ID = 0;
private ContentResolver mContentResolver;
private SharedPreferences prefs;
private Context syncContext;
private int prefsPollutionLevel;
private double …Run Code Online (Sandbox Code Playgroud) 我刚刚开始学习如何使用Dagger,并且已经将我的Backend连接类转换为自动注入.
该类处理Retrofit并执行网络请求.它曾经有静态方法,但现在它是一个对象,例如:
Backend.fetchPost(context, 42); // old way
mBackend.fetchPost(42); // mBackend is an injected field
Run Code Online (Sandbox Code Playgroud)
上下文用于检索AccountManager使用我的后端服务器提供OAuth令牌的上下文.现在自动注入.
这在活动和片段中效果很好,但我无法弄清楚如何注入我的SyncAdapter课程.
实际上,它是一个我无法控制的框架对象,并且AndroidInjections没有准备好注入这种类的静态方法.
这是我想要工作的代码:
/**
* Handle the transfer of data between the backend and the app, using the Android sync adapter framework.
*/
public class SyncAdapter extends AbstractThreadedSyncAdapter {
@Inject
public Backend mBackend; // can't use constructor injection,
// so might aswell use a public field
public SyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
public SyncAdapter(Context …Run Code Online (Sandbox Code Playgroud) 我已经构建了一个联系人同步适配器.这一切都很好,但我还需要一件事.如果由于某种原因导致同步无法成功完成,我希望在同步失败时显示Google帐户显示的消息

android sync contactscontract android-syncadapter android-contacts
我已经阅读了存在的syncadapter的每一个细节,我理解它是如何工作的,但我找不到任何关于是否可以不让用户不同步数据的信息.
例如,如果我使用syncadapter将我的应用程序的所有数据与服务器同步,显然我不希望用户能够从帐户屏幕检查"不同步数据",所以我想知道是否有一种方法可以将所有这些数据与同步适配器同步,方法是不选中复选框以取消同步,或者创建用户无法修改的隐藏同步帐户.
如果在这种情况下使用同步适配器是错误的上下文,我会欣赏一些更好的方法来实现我需要的方法或正确方向的标题.我认为使用syncadapter 可能是错误的,我可能必须实现自己的自定义服务,我只需要一个例子或者其他东西让我朝着正确的方向前进.
谢谢您的帮助.
我的应用程序需要定期向服务器请求新数据.我已经研究过这个,很多人建议使用同步适配器与服务器同步,但是我的要求发生了变化,我需要做以下过程.是否仍然建议使用同步适配器,或者我可以使用任何其他库来有效地生成以下Http请求序列.
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
ZipFile imageZipFile;
/*this is a http post request and the size the zipfile is around 1Mb*/
ZipFile resultFile=makeHttpPostRequest(String URL, String payload);
SomeObject result= processZipFile(resultZipFile);
saveData(result);
for(String url:result.getUrls()){
/* this is a HttpGet request which returns a zip file that
contains 8 images , total size of zip would be around 200kb*/
imageZipFile= makeHttpGetRequest(url);
saveImageZipToDisk(imageZipFile)
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我正在发出Http Post请求以获取包含图像URL的一些数据,并使用这些URL来生成新的HttpGet请求.我需要POST的结果以及我的应用程序运行的图像.
这是使用同步适配器的有效方法还是这是完全不可接受的?或者我可以使用Volley/Robo spice将图像请求生成到多个线程吗?对不起,我是新手,但这是我一直在努力解决的问题.
更新:
因此,在回顾了Volley和Robospice的优点和缺点之后,我正在使用凌空,因为我可以自定义代码并对缓存机制有更多的控制权.
我SyncAdapter用于一些服务器客户端同步.在官方的android开发者指南中,提到了触发同步的不同方法.
你只需致电:
ContentResolver.requestSync(ACCOUNT, AUTHORITY, null);
Run Code Online (Sandbox Code Playgroud)
服务器数据更改时(例如,在GCM上).
只需使用一个 ContentObserver
public class TableObserver extends ContentObserver {
@Override
public void onChange(boolean selfChange) {
onChange(selfChange, null);
}
@Override
public void onChange(boolean selfChange, Uri changeUri) {
ContentResolver.requestSync(ACCOUNT, AUTHORITY, null);
}
}
Run Code Online (Sandbox Code Playgroud)
请执行下列操作:
ContentResolver.setSyncAutomatically(ACCOUNT, AUTHORITY, true)
Run Code Online (Sandbox Code Playgroud)
现在,每当有开放的TCP/IP连接时,SyncAdapter都会触发执行同步.
这对我来说是重要而有趣的部分.为此你只需要这样做(至少这是在开发人员指南中写的):
public static final long SECONDS_PER_MINUTE = 60L;
public static final long SYNC_INTERVAL_IN_MINUTES = 60L;
public static final long SYNC_INTERVAL = SYNC_INTERVAL_IN_MINUTES * SECONDS_PER_MINUTE;
ContentResolver.addPeriodicSync(
ACCOUNT,
AUTHORITY,
Bundle.EMPTY,
SYNC_INTERVAL); …Run Code Online (Sandbox Code Playgroud) 我知道这是一个重复的问题,但我看到了整个地方,找不到适合我的解决方案......
我有一个从TMDB API获取电影数据的应用程序,它使用同步适配器逐页获取,基本上它运行很好,除非在应用程序打开且用户不在第一页时运行同步适配器的定期同步,所以我的选择是强制更新电影列表并将用户发送到列表的顶部,这是非常糟糕的体验,因此不被视为一个选项,或者我可以检查应用程序是否正在运行,无论是在前台还是在应用程序中堆栈,它对用户不可见但仍在运行,所以通过搜索得到的最好的是这段代码:
public static boolean isAppRunning(final Context context, final String packageName) {
final ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
final List<ActivityManager.RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
if (procInfos != null) {
for (final ActivityManager.RunningAppProcessInfo processInfo : procInfos) {
if (processInfo.processName.equals(packageName))
return true;
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
但无论出于什么原因,它都无法正常工作并且即使我通过刷卡杀死它也看到应用程序正在运行,起初我认为这是因为我有一个同步适配器可以被认为是运行的应用程序所以我使用了另一个进程它在清单中使用了
android:process=":service"
Run Code Online (Sandbox Code Playgroud)
但它不起作用
还考虑在活动的onStart和onStop中使用变量,但不保证在关闭或杀死应用程序时会调用onStop,因此试图避免使用此方法
这是我的manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="inc.mourad.ahmed.watchme">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<permission
android:name="inc.ahmed.mourad.ACCESS_WATCHME_DATABASE"
android:label="access my movies content provider"
android:protectionLevel="dangerous" />
<permission
android:name="inc.ahmed.mourad.ACCESS_WATCHME_SYNC_SERVICE"
android:label="access …Run Code Online (Sandbox Code Playgroud)