下面列出了android.os.PersistableBundle#putString ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@SuppressWarnings("MissingPermission")
private static JobInfo buildJobInfo(
int jobId,
ComponentName jobServiceComponentName,
Requirements requirements,
String serviceAction,
String servicePackage) {
JobInfo.Builder builder = new JobInfo.Builder(jobId, jobServiceComponentName);
if (requirements.isUnmeteredNetworkRequired()) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
} else if (requirements.isNetworkRequired()) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
}
builder.setRequiresDeviceIdle(requirements.isIdleRequired());
builder.setRequiresCharging(requirements.isChargingRequired());
builder.setPersisted(true);
PersistableBundle extras = new PersistableBundle();
extras.putString(KEY_SERVICE_ACTION, serviceAction);
extras.putString(KEY_SERVICE_PACKAGE, servicePackage);
extras.putInt(KEY_REQUIREMENTS, requirements.getRequirements());
builder.setExtras(extras);
return builder.build();
}
static PersistableBundle getJobExtrasFromIntent(Intent intent) {
PersistableBundle bundle = new PersistableBundle();
bundle.putString(NotificationConstants.EXTRA_NOTIFICATION_ID,
intent.getStringExtra(NotificationConstants.EXTRA_NOTIFICATION_ID));
bundle.putString(NotificationConstants.EXTRA_NOTIFICATION_INFO_ORIGIN,
intent.getStringExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_ORIGIN));
bundle.putString(NotificationConstants.EXTRA_NOTIFICATION_INFO_PROFILE_ID,
intent.getStringExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_PROFILE_ID));
bundle.putBoolean(NotificationConstants.EXTRA_NOTIFICATION_INFO_PROFILE_INCOGNITO,
intent.getBooleanExtra(
NotificationConstants.EXTRA_NOTIFICATION_INFO_PROFILE_INCOGNITO, false));
bundle.putString(NotificationConstants.EXTRA_NOTIFICATION_INFO_TAG,
intent.getStringExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_TAG));
bundle.putInt(NotificationConstants.EXTRA_NOTIFICATION_INFO_ACTION_INDEX,
intent.getIntExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_ACTION_INDEX, -1));
bundle.putString(NotificationConstants.EXTRA_NOTIFICATION_INFO_WEBAPK_PACKAGE,
intent.getStringExtra(
NotificationConstants.EXTRA_NOTIFICATION_INFO_WEBAPK_PACKAGE));
bundle.putString(NotificationConstants.EXTRA_NOTIFICATION_ACTION, intent.getAction());
// Only primitives can be set on a persistable bundle, so extract the raw reply.
bundle.putString(NotificationConstants.EXTRA_NOTIFICATION_REPLY,
NotificationPlatformBridge.getNotificationReply(intent));
return bundle;
}
@TargetApi(VERSION_CODES.LOLLIPOP_MR1)
public static PersistableBundle bundleToPersistableBundle(Bundle bundle) {
Set<String> keySet = bundle.keySet();
PersistableBundle persistableBundle = new PersistableBundle();
for (String key : keySet) {
Object value = bundle.get(key);
if (value instanceof Boolean) {
persistableBundle.putBoolean(key, (boolean) value);
} else if (value instanceof Integer) {
persistableBundle.putInt(key, (int) value);
} else if (value instanceof String) {
persistableBundle.putString(key, (String) value);
} else if (value instanceof String[]) {
persistableBundle.putStringArray(key, (String[]) value);
} else if (value instanceof Bundle) {
PersistableBundle innerBundle = bundleToPersistableBundle((Bundle) value);
persistableBundle.putPersistableBundle(key, innerBundle);
}
}
return persistableBundle;
}
public static PersistableBundle fromAddress(android.location.Address address) {
if (address == null) {
return null;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
PersistableBundle persistableBundle = new PersistableBundle();
persistableBundle.putString("country", address.getLocale().getCountry());
persistableBundle.putString("language", address.getLocale().getLanguage());
persistableBundle.putString("variant", address.getLocale().getVariant());
persistableBundle.putString("locality", address.getLocality());
persistableBundle.putString("subLocality", address.getSubLocality());
persistableBundle.putString("adminArea", address.getAdminArea());
persistableBundle.putString("subAdminArea", address.getSubAdminArea());
persistableBundle.putString("countryName", address.getCountryName());
return persistableBundle;
} else {
return null;
}
}
/**
* Manually requests a job to run now.
*
* <p>To check the current status of the sync, register a {@link
* android.content.BroadcastReceiver} with an {@link android.content.IntentFilter} which checks
* for the action {@link #ACTION_SYNC_STATUS_CHANGED}.
*
* <p>The sync status is an extra parameter in the {@link Intent} with key {@link #SYNC_STATUS}.
* The sync status is either {@link #SYNC_STARTED} or {@link #SYNC_FINISHED}.
*
* <p>Check that the value of {@link #BUNDLE_KEY_INPUT_ID} matches your {@link
* android.media.tv.TvInputService}. If you're calling this from your setup activity, you can
* get the extra parameter {@link TvInputInfo#EXTRA_INPUT_ID}.
*
* <p>
*
* @param context Application's context.
* @param inputId Component name for the app's TvInputService. This can be received through an
* Intent extra parameter {@link TvInputInfo#EXTRA_INPUT_ID}.
* @param syncDuration The duration of EPG content to fetch in milliseconds. For a manual sync,
* this should be relatively short. For a background sync this should be long.
* @param jobServiceComponent The {@link EpgSyncJobService} class that will run.
*/
public static void requestImmediateSync(
Context context, String inputId, long syncDuration, ComponentName jobServiceComponent) {
if (jobServiceComponent.getClass().isAssignableFrom(EpgSyncJobService.class)) {
throw new IllegalArgumentException("This class does not extend EpgSyncJobService");
}
PersistableBundle persistableBundle = new PersistableBundle();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
persistableBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
persistableBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
}
persistableBundle.putString(EpgSyncJobService.BUNDLE_KEY_INPUT_ID, inputId);
persistableBundle.putLong(EpgSyncJobService.BUNDLE_KEY_SYNC_PERIOD, syncDuration);
JobInfo.Builder builder = new JobInfo.Builder(REQUEST_SYNC_JOB_ID, jobServiceComponent);
JobInfo jobInfo =
builder.setExtras(persistableBundle)
.setOverrideDeadline(EpgSyncJobService.OVERRIDE_DEADLINE_MILLIS)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.build();
scheduleJob(context, jobInfo);
if (DEBUG) {
Log.d(TAG, "Single job scheduled");
}
}
@Deprecated
public static void requestImmediateSync1(Context context, String inputId, long syncDuration,
ComponentName jobServiceComponent) {
if (jobServiceComponent.getClass().isAssignableFrom(EpgSyncJobService.class)) {
throw new IllegalArgumentException("This class does not extend EpgSyncJobService");
}
PersistableBundle persistableBundle = new PersistableBundle();
if (Build.VERSION.SDK_INT >= 22) {
persistableBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
persistableBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
}
persistableBundle.putString(EpgSyncJobService.BUNDLE_KEY_INPUT_ID, inputId);
persistableBundle.putLong("bundle_key_sync_period", syncDuration);
JobInfo.Builder builder = new JobInfo.Builder(1, jobServiceComponent);
JobInfo jobInfo = builder
.setExtras(persistableBundle)
.setOverrideDeadline(1000)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.build();
scheduleJob(context, jobInfo);
Log.d(TAG, "Single job scheduled");
}
@SuppressWarnings("MissingPermission")
private static JobInfo buildJobInfo(
int jobId,
ComponentName jobServiceComponentName,
Requirements requirements,
String serviceAction,
String servicePackage) {
JobInfo.Builder builder = new JobInfo.Builder(jobId, jobServiceComponentName);
if (requirements.isUnmeteredNetworkRequired()) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
} else if (requirements.isNetworkRequired()) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
}
builder.setRequiresDeviceIdle(requirements.isIdleRequired());
builder.setRequiresCharging(requirements.isChargingRequired());
builder.setPersisted(true);
PersistableBundle extras = new PersistableBundle();
extras.putString(KEY_SERVICE_ACTION, serviceAction);
extras.putString(KEY_SERVICE_PACKAGE, servicePackage);
extras.putInt(KEY_REQUIREMENTS, requirements.getRequirements());
builder.setExtras(extras);
return builder.build();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
static public boolean checkAndRequestIslandPermission(Context context) {
final String TYPE_DELEGATION = "com.oasisfeng.island.delegation";
final String DELEGATION_APP_OPS = "-island-delegation-app-ops";
final String DELEGATION_PACKAGE_ACCESS = "delegation-package-access";
final RestrictionsManager rm = (RestrictionsManager) context.getSystemService(Context.RESTRICTIONS_SERVICE);
if (rm != null && rm.hasRestrictionsProvider()) { // Otherwise, current user is not managed by Island or the version of Island is too low.
final String[] delegations = rm.getApplicationRestrictions().getStringArray(TYPE_DELEGATION);
if (delegations == null || !Arrays.asList(delegations).contains(DELEGATION_PACKAGE_ACCESS)) {
final PersistableBundle request = new PersistableBundle();
request.putString(RestrictionsManager.REQUEST_KEY_DATA, DELEGATION_PACKAGE_ACCESS);
rm.requestPermission(TYPE_DELEGATION, "cf.playhi.freezeyou.android.app-ops", request);
} else {
return true;
}
}
return false;
}
/**
* Initializes a job that will periodically update the app's channels and programs.
*
* @param context Application's context.
* @param inputId Component name for the app's TvInputService. This can be received through an
* Intent extra parameter {@link TvInputInfo#EXTRA_INPUT_ID}.
* @param jobServiceComponent The {@link EpgSyncJobService} component name that will run.
* @param fullSyncPeriod The period between when the job will run a full background sync in
* milliseconds.
* @param syncDuration The duration of EPG content to fetch in milliseconds. For a manual sync,
* this should be relatively short. For a background sync this should be long.
*/
public static void setUpPeriodicSync(
Context context,
String inputId,
ComponentName jobServiceComponent,
long fullSyncPeriod,
long syncDuration) {
if (jobServiceComponent.getClass().isAssignableFrom(EpgSyncJobService.class)) {
throw new IllegalArgumentException("This class does not extend EpgSyncJobService");
}
PersistableBundle persistableBundle = new PersistableBundle();
persistableBundle.putString(EpgSyncJobService.BUNDLE_KEY_INPUT_ID, inputId);
persistableBundle.putLong(EpgSyncJobService.BUNDLE_KEY_SYNC_PERIOD, syncDuration);
JobInfo.Builder builder = new JobInfo.Builder(PERIODIC_SYNC_JOB_ID, jobServiceComponent);
JobInfo jobInfo =
builder.setExtras(persistableBundle)
.setPeriodic(fullSyncPeriod)
.setPersisted(true)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.build();
scheduleJob(context, jobInfo);
if (DEBUG) {
Log.d(TAG, "Job has been scheduled for every " + fullSyncPeriod + "ms");
}
}
/**
* Manually requests a job to run now.
*
* <p>To check the current status of the sync, register a {@link
* android.content.BroadcastReceiver} with an {@link android.content.IntentFilter} which checks
* for the action {@link #ACTION_SYNC_STATUS_CHANGED}.
*
* <p>The sync status is an extra parameter in the {@link Intent} with key {@link #SYNC_STATUS}.
* The sync status is either {@link #SYNC_STARTED} or {@link #SYNC_FINISHED}.
*
* <p>Check that the value of {@link #BUNDLE_KEY_INPUT_ID} matches your {@link
* android.media.tv.TvInputService}. If you're calling this from your setup activity, you can
* get the extra parameter {@link TvInputInfo#EXTRA_INPUT_ID}.
*
* <p>
*
* @param context Application's context.
* @param inputId Component name for the app's TvInputService. This can be received through an
* Intent extra parameter {@link TvInputInfo#EXTRA_INPUT_ID}.
* @param syncDuration The duration of EPG content to fetch in milliseconds. For a manual sync,
* this should be relatively short. For a background sync this should be long.
* @param jobServiceComponent The {@link EpgSyncJobService} class that will run.
*/
public static void requestImmediateSync(
Context context, String inputId, long syncDuration, ComponentName jobServiceComponent) {
if (jobServiceComponent.getClass().isAssignableFrom(EpgSyncJobService.class)) {
throw new IllegalArgumentException("This class does not extend EpgSyncJobService");
}
PersistableBundle persistableBundle = new PersistableBundle();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
persistableBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
persistableBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
}
persistableBundle.putString(EpgSyncJobService.BUNDLE_KEY_INPUT_ID, inputId);
persistableBundle.putLong(EpgSyncJobService.BUNDLE_KEY_SYNC_PERIOD, syncDuration);
JobInfo.Builder builder = new JobInfo.Builder(REQUEST_SYNC_JOB_ID, jobServiceComponent);
JobInfo jobInfo =
builder.setExtras(persistableBundle)
.setOverrideDeadline(EpgSyncJobService.OVERRIDE_DEADLINE_MILLIS)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.build();
scheduleJob(context, jobInfo);
if (DEBUG) {
Log.d(TAG, "Single job scheduled");
}
}
private void scheduleJob(ThreadInfo threadInfo, long nextRunTime) {
long delay = nextRunTime - System.currentTimeMillis();
PersistableBundle bundle = new PersistableBundle();
bundle.putLong(THREAD_ID_EXTRA, threadInfo.threadId);
bundle.putString(BOARD_NAME_EXTRA, threadInfo.boardName);
bundle.putString(BOARD_TITLE_EXTRA, threadInfo.boardTitle);
bundle.putInt(WATCHED_EXTRA, threadInfo.watched ? 1 : 0);
bundle.putLong(LAST_REFRESH_TIME_EXTRA, threadInfo.refreshTimestamp);
bundle.putInt(RESULT_KEY, RESULT_SCHEDULED);
bundle.putInt(BACKGROUNDED_KEY, backgrounded ? 1 : 0);
ComponentName serviceComponent = new ComponentName(context, RefreshJobService.class);
JobInfo jobInfo = new JobInfo.Builder(JOB_ID, serviceComponent)
.setMinimumLatency(delay)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setRequiresCharging(false)
.setExtras(bundle)
.build();
refreshScheduler.schedule(jobInfo);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Synthetic PersistableBundle toPersistableBundle() {
PersistableBundle bundle = new PersistableBundle();
bundle.putString(EXTRA_ID, id);
bundle.putInt(EXTRA_CONNECTION_ENABLED, connectionEnabled ? 1 : 0);
bundle.putInt(EXTRA_READABILITY_ENABLED, readabilityEnabled ? 1 : 0);
bundle.putInt(EXTRA_ARTICLE_ENABLED, articleEnabled ? 1 : 0);
bundle.putInt(EXTRA_COMMENTS_ENABLED, commentsEnabled ? 1 : 0);
bundle.putInt(EXTRA_NOTIFICATION_ENABLED, notificationEnabled ? 1 : 0);
return bundle;
}
/**
* Copy all entries in the {@link Bundle} that can be part of a {@link PersistableBundle}.
*
* @param bundle the {@link Bundle} to convert.
* @return a result object contain the resulting {@link PersistableBundle} and whether any of
* the keys failed.
*/
static Result convert(Bundle bundle) {
PersistableBundle persistableBundle = new PersistableBundle();
Set<String> failedKeys = new HashSet<>();
for (String key : bundle.keySet()) {
Object obj = bundle.get(key);
if (obj == null) {
persistableBundle.putString(key, null);
} else if (obj instanceof Boolean) {
persistableBundle.putBoolean(key, (Boolean) obj);
} else if (obj instanceof boolean[]) {
persistableBundle.putBooleanArray(key, (boolean[]) obj);
} else if (obj instanceof Double) {
persistableBundle.putDouble(key, (Double) obj);
} else if (obj instanceof double[]) {
persistableBundle.putDoubleArray(key, (double[]) obj);
} else if (obj instanceof Integer) {
persistableBundle.putInt(key, (Integer) obj);
} else if (obj instanceof int[]) {
persistableBundle.putIntArray(key, (int[]) obj);
} else if (obj instanceof Long) {
persistableBundle.putLong(key, (Long) obj);
} else if (obj instanceof long[]) {
persistableBundle.putLongArray(key, (long[]) obj);
} else if (obj instanceof String) {
persistableBundle.putString(key, (String) obj);
} else if (obj instanceof String[]) {
persistableBundle.putStringArray(key, (String[]) obj);
} else {
failedKeys.add(key);
}
}
return new Result(persistableBundle, failedKeys);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public void startJobScheduler(String className) {
if (AliveJobService.isLive() || isBelowLOLLIPOP()) {
return;
}
jobScheduleer.cancel(JOB_ID);
// 构建JobInfo对象,传递给JobSchedulerService
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, new ComponentName(BaseApplication.getInstance(), AliveJobService.class));
if (Build.VERSION.SDK_INT >= 24) {
builder.setMinimumLatency(JobInfo.DEFAULT_INITIAL_BACKOFF_MILLIS); //执行的最小延迟时间
builder.setOverrideDeadline(JobInfo.DEFAULT_INITIAL_BACKOFF_MILLIS); //执行的最长延时时间
builder.setMinimumLatency(JobInfo.DEFAULT_INITIAL_BACKOFF_MILLIS);
builder.setBackoffCriteria(JobInfo.DEFAULT_INITIAL_BACKOFF_MILLIS, JobInfo.BACKOFF_POLICY_LINEAR);//线性重试方案
} else {
builder.setPeriodic(JobInfo.DEFAULT_INITIAL_BACKOFF_MILLIS);
}
builder.setPersisted(true); // 设置设备重启时,执行该任务
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
builder.setRequiresCharging(true); // 当插入充电器,执行该任务
// 设置设备重启时,执行该任务
builder.setPersisted(true);
// 当插入充电器,执行该任务
builder.setRequiresCharging(true);
PersistableBundle persistableBundle = new PersistableBundle();
persistableBundle.putString(PENDING_CLASS_NAME, className);
builder.setExtras(persistableBundle);
JobInfo info = builder.build();
//开始定时执行该系统任务
int result = jobScheduleer.schedule(info);
if (result == JobScheduler.RESULT_FAILURE) {
CommonLogger.e("jobService启动失败");
} else {
CommonLogger.e("jobService启动成功");
}
}
/**
* Copy important intent extras from the launching intent launchIntent into newBundle.
*/
public static void prepareDeviceAdminExtras(Intent launchIntent, PersistableBundle newBundle) {
if (isSynchronousAuthLaunch(launchIntent)) {
boolean isSetupWizard = launchIntent.getBooleanExtra(EXTRA_IS_SETUP_WIZARD, false);
// Store as String in new bundle, as API 21 doesn't support putBoolean.
newBundle.putString(EXTRA_IS_SETUP_WIZARD, Boolean.toString(isSetupWizard));
Account addedAccount = getAddedAccount(launchIntent);
if (addedAccount != null) {
newBundle.putString(EXTRA_ACCOUNT_NAME, addedAccount.name);
}
}
}
/**
* All fields are stored in a corresponding key in the persistable bundle.
*
* {@link #extras} is a Bundle and can contain parcelable objects. But only the type Account
* is allowed {@link ContentResolver#validateSyncExtrasBundle(Bundle)} that can't be stored in
* a PersistableBundle. For every value of type Account with key 'key', we store a
* PersistableBundle containing account information at key 'ACCOUNT:key'. The Account object
* can be reconstructed using this.
*
* We put a flag with key 'SyncManagerJob', to identify while reconstructing a sync operation
* from a bundle whether the bundle actually contains information about a sync.
* @return A persistable bundle containing all information to re-construct the sync operation.
*/
PersistableBundle toJobInfoExtras() {
// This will be passed as extras bundle to a JobScheduler job.
PersistableBundle jobInfoExtras = new PersistableBundle();
PersistableBundle syncExtrasBundle = new PersistableBundle();
for (String key: extras.keySet()) {
Object value = extras.get(key);
if (value instanceof Account) {
Account account = (Account) value;
PersistableBundle accountBundle = new PersistableBundle();
accountBundle.putString("accountName", account.name);
accountBundle.putString("accountType", account.type);
// This is stored in jobInfoExtras so that we don't override a user specified
// sync extra with the same key.
jobInfoExtras.putPersistableBundle("ACCOUNT:" + key, accountBundle);
} else if (value instanceof Long) {
syncExtrasBundle.putLong(key, (Long) value);
} else if (value instanceof Integer) {
syncExtrasBundle.putInt(key, (Integer) value);
} else if (value instanceof Boolean) {
syncExtrasBundle.putBoolean(key, (Boolean) value);
} else if (value instanceof Float) {
syncExtrasBundle.putDouble(key, (double) (float) value);
} else if (value instanceof Double) {
syncExtrasBundle.putDouble(key, (Double) value);
} else if (value instanceof String) {
syncExtrasBundle.putString(key, (String) value);
} else if (value == null) {
syncExtrasBundle.putString(key, null);
} else {
Slog.e(TAG, "Unknown extra type.");
}
}
jobInfoExtras.putPersistableBundle("syncExtras", syncExtrasBundle);
jobInfoExtras.putBoolean("SyncManagerJob", true);
jobInfoExtras.putString("provider", target.provider);
jobInfoExtras.putString("accountName", target.account.name);
jobInfoExtras.putString("accountType", target.account.type);
jobInfoExtras.putInt("userId", target.userId);
jobInfoExtras.putInt("owningUid", owningUid);
jobInfoExtras.putString("owningPackage", owningPackage);
jobInfoExtras.putInt("reason", reason);
jobInfoExtras.putInt("source", syncSource);
jobInfoExtras.putBoolean("allowParallelSyncs", allowParallelSyncs);
jobInfoExtras.putInt("jobId", jobId);
jobInfoExtras.putBoolean("isPeriodic", isPeriodic);
jobInfoExtras.putInt("sourcePeriodicId", sourcePeriodicId);
jobInfoExtras.putLong("periodMillis", periodMillis);
jobInfoExtras.putLong("flexMillis", flexMillis);
jobInfoExtras.putLong("expectedRuntime", expectedRuntime);
jobInfoExtras.putInt("retries", retries);
jobInfoExtras.putInt("syncExemptionFlag", syncExemptionFlag);
return jobInfoExtras;
}
private int runSuspend(boolean suspendedState) {
final PrintWriter pw = getOutPrintWriter();
int userId = UserHandle.USER_SYSTEM;
String dialogMessage = null;
final PersistableBundle appExtras = new PersistableBundle();
final PersistableBundle launcherExtras = new PersistableBundle();
String opt;
while ((opt = getNextOption()) != null) {
switch (opt) {
case "--user":
userId = UserHandle.parseUserArg(getNextArgRequired());
break;
case "--dialogMessage":
dialogMessage = getNextArgRequired();
break;
case "--ael":
case "--aes":
case "--aed":
case "--lel":
case "--les":
case "--led":
final String key = getNextArgRequired();
final String val = getNextArgRequired();
if (!suspendedState) {
break;
}
final PersistableBundle bundleToInsert =
opt.startsWith("--a") ? appExtras : launcherExtras;
switch (opt.charAt(4)) {
case 'l':
bundleToInsert.putLong(key, Long.valueOf(val));
break;
case 'd':
bundleToInsert.putDouble(key, Double.valueOf(val));
break;
case 's':
bundleToInsert.putString(key, val);
break;
}
break;
default:
pw.println("Error: Unknown option: " + opt);
return 1;
}
}
final String packageName = getNextArg();
if (packageName == null) {
pw.println("Error: package name not specified");
return 1;
}
final String callingPackage =
(Binder.getCallingUid() == Process.ROOT_UID) ? "root" : "com.android.shell";
try {
mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
appExtras, launcherExtras, dialogMessage, callingPackage, userId);
pw.println("Package " + packageName + " new suspended state: "
+ mInterface.isPackageSuspendedForUser(packageName, userId));
return 0;
} catch (RemoteException | IllegalArgumentException e) {
pw.println(e.toString());
return 1;
}
}
@SuppressWarnings("MissingPermission")
private static JobInfo buildJobInfo(
int jobId,
ComponentName jobServiceComponentName,
Requirements requirements,
String serviceAction,
String servicePackage) {
JobInfo.Builder builder = new JobInfo.Builder(jobId, jobServiceComponentName);
int networkType;
switch (requirements.getRequiredNetworkType()) {
case Requirements.NETWORK_TYPE_NONE:
networkType = JobInfo.NETWORK_TYPE_NONE;
break;
case Requirements.NETWORK_TYPE_ANY:
networkType = JobInfo.NETWORK_TYPE_ANY;
break;
case Requirements.NETWORK_TYPE_UNMETERED:
networkType = JobInfo.NETWORK_TYPE_UNMETERED;
break;
case Requirements.NETWORK_TYPE_NOT_ROAMING:
if (Util.SDK_INT >= 24) {
networkType = JobInfo.NETWORK_TYPE_NOT_ROAMING;
} else {
throw new UnsupportedOperationException();
}
break;
case Requirements.NETWORK_TYPE_METERED:
if (Util.SDK_INT >= 26) {
networkType = JobInfo.NETWORK_TYPE_METERED;
} else {
throw new UnsupportedOperationException();
}
break;
default:
throw new UnsupportedOperationException();
}
builder.setRequiredNetworkType(networkType);
builder.setRequiresDeviceIdle(requirements.isIdleRequired());
builder.setRequiresCharging(requirements.isChargingRequired());
builder.setPersisted(true);
PersistableBundle extras = new PersistableBundle();
extras.putString(KEY_SERVICE_ACTION, serviceAction);
extras.putString(KEY_SERVICE_PACKAGE, servicePackage);
extras.putInt(KEY_REQUIREMENTS, requirements.getRequirementsData());
builder.setExtras(extras);
return builder.build();
}
/**
* Schedules the JobScheduler service.
*
* @param transportContext Contains information about the backend and the priority.
* @param attemptNumber Number of times the JobScheduler has tried to log for this backend.
*/
@Override
public void schedule(TransportContext transportContext, int attemptNumber) {
ComponentName serviceComponent = new ComponentName(context, JobInfoSchedulerService.class);
JobScheduler jobScheduler =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
int jobId = getJobId(transportContext);
// Check if there exists a job scheduled for this backend name.
if (isJobServiceOn(jobScheduler, jobId, attemptNumber)) {
Logging.d(
LOG_TAG, "Upload for context %s is already scheduled. Returning...", transportContext);
return;
}
long nextCallTime = eventStore.getNextCallTime(transportContext);
// Schedule the build.
JobInfo.Builder builder =
config.configureJob(
new JobInfo.Builder(jobId, serviceComponent),
transportContext.getPriority(),
nextCallTime,
attemptNumber);
PersistableBundle bundle = new PersistableBundle();
bundle.putInt(ATTEMPT_NUMBER, attemptNumber);
bundle.putString(BACKEND_NAME, transportContext.getBackendName());
bundle.putInt(EVENT_PRIORITY, PriorityMapping.toInt(transportContext.getPriority()));
if (transportContext.getExtras() != null) {
bundle.putString(EXTRAS, encodeToString(transportContext.getExtras(), DEFAULT));
}
builder.setExtras(bundle);
Logging.d(
LOG_TAG,
"Scheduling upload for context %s with jobId=%d in %dms(Backend next call timestamp %d). Attempt %d",
transportContext,
jobId,
config.getScheduleDelay(transportContext.getPriority(), nextCallTime, attemptNumber),
nextCallTime,
attemptNumber);
jobScheduler.schedule(builder.build());
}
PersistableBundle toPersistableBundle() {
PersistableBundle bundle = new PersistableBundle();
bundle.putString("url", url);
return bundle;
}