IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 11日历中添加账户跳转失败 -> 正文阅读

[移动开发]Android 11日历中添加账户跳转失败

现象:在日历应用中点击添加账户跳转失败,在设置中点击添加账户正常

日历中添加账户入口
// vendor/mediatek/proprietary/packages/apps/Calendar/src/com/android/calendar/CalendarSettingsActivity.java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
   if (item.getItemId() == android.R.id.home) {
       finish();
       return true;
   } else if (item.getItemId() == R.id.action_add_account) {
   	   // 这里ACTION_ADD_ACCOUNT = "android.settings.ADD_ACCOUNT_SETTINGS"
       Intent nextIntent = new Intent(Settings.ACTION_ADD_ACCOUNT);
       final String[] array = { "com.android.calendar" };
       // 这里Settings.EXTRA_AUTHORITIES = authorities
       nextIntent.putExtra(Settings.EXTRA_AUTHORITIES, array);
       nextIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
       startActivity(nextIntent);
       return true;
   }
   return super.onOptionsItemSelected(item);
}
设置中添加账户入口
// packages/apps/Settings/src/com/android/settings/accounts/AccountPreferenceController.java

@Override
public boolean onPreferenceClick(Preference preference) {
   final int metricsCategory = mFragment.getMetricsCategory();
   // Check the preference
   final int count = mProfiles.size();
   for (int i = 0; i < count; i++) {
        ProfileData profileData = mProfiles.valueAt(i);
        if (preference == profileData.addAccountPreference) {
            mMetricsFeatureProvider.logClickedPreference(preference, metricsCategory);
            // 这里ACTION_ADD_ACCOUNT = "android.settings.ADD_ACCOUNT_SETTINGS"
            Intent intent = new Intent(ACTION_ADD_ACCOUNT);
            intent.putExtra(EXTRA_USER, profileData.userInfo.getUserHandle());
            // 这里EXTRA_AUTHORITIES = authorities,打印此处的mAuthorities为空
            intent.putExtra(EXTRA_AUTHORITIES, mAuthorities); 
            mContext.startActivity(intent);
            return true;
        }
        // ...
   }
   return false;
}

这两处都是跳转到 AddAccountSettings.java中,然后又经过一些条件判断调用其中的requestChooseAccount()方法跳转到ChooseAccountActivity.java

// packages/apps/Settings/src/com/android/settings/accounts/AddAccountSettings.java

@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   // ...
   if (um.isUserUnlocked(mUserHandle)) {
       requestChooseAccount();
   } else {
   	   // If the user is locked by fbe: we couldn't start the authenticator. So we must ask the
       // user to unlock it first.
       ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(this);
       if (!helper.launchConfirmationActivity(UNLOCK_WORK_PROFILE_REQUEST,
               getString(R.string.unlock_set_unlock_launch_picker_title),false,
                    mUserHandle.getIdentifier())) {
           requestChooseAccount();
       }
   }
}

// 这里又跳转到ChooseAccountActivity,实际就是拉起ChooseAccountFragment
private void requestChooseAccount() {
   final String[] authorities =
           getIntent().getStringArrayExtra(AccountPreferenceBase.AUTHORITIES_FILTER_KEY);
   final String[] accountTypes =
           getIntent().getStringArrayExtra(AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY);
   final Intent intent = new Intent(this, Settings.ChooseAccountActivity.class);
   if (authorities != null) {
       intent.putExtra(AccountPreferenceBase.AUTHORITIES_FILTER_KEY, authorities);
   }
   if (accountTypes != null) {
       intent.putExtra(AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY, accountTypes);
   }
   intent.putExtra(EXTRA_USER, mUserHandle);
   startActivityForResult(intent, CHOOSE_ACCOUNT_REQUEST);
}

ChooseAccountFragment.java中调用ChooseAccountPreferenceController.java的initialize()方法

// packages/apps/Settings/src/com/android/settings/accounts/ChooseAccountFragment.java

@Override
public void onAttach(Context context) {
   super.onAttach(context);
   // AUTHORITIES_FILTER_KEY = "authorities"
   final String[] authorities = getIntent().getStringArrayExtra(
            AccountPreferenceBase.AUTHORITIES_FILTER_KEY);
   // ACCOUNT_TYPES_FILTER_KEY = "account_types"
   final String[] accountTypesFilter = getIntent().getStringArrayExtra(
            AccountPreferenceBase.ACCOUNT_TYPES_FILTER_KEY);
   final UserManager userManager = UserManager.get(getContext());
   final UserHandle userHandle = Utils.getSecureTargetUser(getActivity().getActivityToken(),
                userManager, null /* arguments */, getIntent().getExtras());
   // 这里调用ChooseAccountPreferenceController中的initialize()方法
   use(ChooseAccountPreferenceController.class).initialize(authorities, accountTypesFilter,
           userHandle, getActivity());
}

最后在ChooseAccountPreferenceController.java判断是否显示可添加的账号类型列表。

// packages/apps/Settings/src/com/android/settings/accounts/ChooseAccountPreferenceController.java

public void initialize(String[] authorities, String[] accountTypesFilter, UserHandle userHandle,
         Activity activity) {
    mActivity = activity;
    mAuthorities = authorities;
    mUserHandle = userHandle;
    // 如果是从Setting进入,mAuthorities=null;
    // 如果是从Calendar进入,mAuthorities=com.android.calendar(通过intent传过来的)
    if (accountTypesFilter != null) {
        mAccountTypesFilter = new HashSet<>();
        for (String accountType : accountTypesFilter) {
             mAccountTypesFilter.add(accountType);
        }
    }
}
// ...
private void updateAuthDescriptions() {
   mAuthDescs = AccountManager.get(mContext).getAuthenticatorTypesAsUser(
           mUserHandle.getIdentifier());
   for (int i = 0; i < mAuthDescs.length; i++) { //这里可能有多个值
       //mAuthDescs[i].type的分别为com.android.email和com.android.email.pop3	 
       //mAuthDescs[i]的值分别为
       //AuthenticatorDescription {type=com.android.email}
       //AuthenticatorDescription {type=com.android.email.pop3}
       mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]);    
   }
   onAuthDescriptionsUpdated();
}

private void onAuthDescriptionsUpdated() {
    // Create list of providers to show on preference screen
    for (int i = 0; i < mAuthDescs.length; i++) {
         final String accountType = mAuthDescs[i].type;
         final CharSequence providerName = getLabelForType(accountType);
         // 此处的providerName值为个人(IMAP)和个人(POP3)   这里可能有多个值
         
         // Skip preferences for authorities not specified. If no authorities specified,
         // then include them all.
         final List<String> accountAuths = getAuthoritiesForAccountType(accountType);
         // 此处的accountAuths的值为com.android.email.provider
         
         boolean addAccountPref = true;
         // 从Setting中进行添加账户传过来的mAuthorities值为null,跳过下面的if;这个时候addAccountPref的值为true
         // 从Calendar进行添加账户传过来的mAuthorities值为com.android.calendar,进入上面if中;但是accountAuths和mAuthorities的值不匹配,此时mAuthorities的值为false
         if (mAuthorities != null && mAuthorities.length > 0 && accountAuths != null) {
             addAccountPref = false;
             for (int k = 0; k < mAuthorities.length; k++) {   
                  if (accountAuths.contains(mAuthorities[k])) {
                      addAccountPref = true;
                      break;
                  }
             }
         }
         if (addAccountPref && mAccountTypesFilter != null
                  && !mAccountTypesFilter.contains(accountType)) {
             addAccountPref = false;
         } 
         // addAccountPref的值为false,mProviderList.size()==0
         if (addAccountPref) {
             mProviderList.add(new ProviderEntry(providerName, accountType));
         } else {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "Skipped pref " + providerName + ": has no authority we need");
             }
         }
     }
     final Context context = mScreen.getContext();
     if (mProviderList.size() == 1) {
         // There's only one provider that matches. If it is disabled by admin show the
         // support dialog otherwise run it.
         final RestrictedLockUtils.EnforcedAdmin admin =
                 RestrictedLockUtilsInternal.checkIfAccountManagementDisabled(
                            context, mProviderList.get(0).getType(), mUserHandle.getIdentifier());
         if (admin != null) {
             mActivity.setResult(RESULT_CANCELED,
                     RestrictedLockUtils.getShowAdminSupportDetailsIntent(
                                context, admin));
             mActivity.finish();
         } else {
             finishWithAccountType(mProviderList.get(0).getType());
         }
     } else if (mProviderList.size() > 0) { // mProviderList不为空,显示可添加的账户类型列表
         Collections.sort(mProviderList);
         for (ProviderEntry pref : mProviderList) {
              final Drawable drawable = getDrawableForType(pref.getType());
              final ProviderPreference p = new ProviderPreference(context,
                        pref.getType(), drawable, pref.getName());
              p.setKey(pref.getType().toString());
              p.checkAccountManagementAndSetDisabled(mUserHandle.getIdentifier());
              mScreen.addPreference(p);
         }
    } else {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            final StringBuilder auths = new StringBuilder();
            for (String a : mAuthorities) {
                 auths.append(a);
                 auths.append(' ');
            }
            Log.v(TAG, "No providers found for authorities: " + auths);
        }
        // mProviderList.size()==0,直接退出
        mActivity.setResult(RESULT_CANCELED);
        mActivity.finish();
    }
}
// ...

所以我们只需修改传过来的mAuthorities的数组中包含com.android.email.provider,或者直接不传值

// vendor/mediatek/proprietary/packages/apps/Calendar/src/com/android/calendar/CalendarSettingsActivity.java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
   if (item.getItemId() == android.R.id.home) {
       finish();
       return true;
   } else if (item.getItemId() == R.id.action_add_account) {
       Intent nextIntent = new Intent(Settings.ACTION_ADD_ACCOUNT);
       // 加入"com.android.email.provider"
       final String[] array = { "com.android.calendar", "com.android.email.provider"};
       nextIntent.putExtra(Settings.EXTRA_AUTHORITIES, array); // 或者直接注释此行
       nextIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
       startActivity(nextIntent);
       return true;
   }
   return super.onOptionsItemSelected(item);
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-08 08:15:26  更:2022-05-08 08:16:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 0:48:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码