Android 信任锚不仅在设备上找到,而且在模拟器上运行?
所有内容都在标题中,我不明白为什么我的代码可以在模拟器中工作,但不能在我的设备上工作。它抛出一个“未找到信任锚点异常”!怎么可能呢?我尝试了关于trustManager的okhttp.builder的实现,但仍然。。请帮帮我 这是我的班级:Android 信任锚不仅在设备上找到,而且在模拟器上运行?,android,android-emulator,anchor,okhttp3,Android,Android Emulator,Anchor,Okhttp3,所有内容都在标题中,我不明白为什么我的代码可以在模拟器中工作,但不能在我的设备上工作。它抛出一个“未找到信任锚点异常”!怎么可能呢?我尝试了关于trustManager的okhttp.builder的实现,但仍然。。请帮帮我 这是我的班级: public abstract class NewsFragment extends Fragment { private static final String TAAG = NewsFragment.class.getSimpleName();
public abstract class NewsFragment extends Fragment {
private static final String TAAG = NewsFragment.class.getSimpleName();
protected ItemAdapter mArticleAdapter;
protected RecyclerView mRecyclerView;
protected NewsFragment.OnNewSelectedInterface mListener;
protected ItemAdapter.OnNewsInsertedInterface mListener2;
protected RecyclerView.LayoutManager mManager;
protected SwipeRefreshLayout mSwipeRefreshLayout;
public static final String KEY_LIST = "key_list";
public interface OnNewSelectedInterface {
void onListNewSelected(int index, ArrayList<Article> articles);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
setHasOptionsMenu(true);
View view = inflater.inflate(R.layout.list_present_news, container, false);
mListener = (NewsFragment.OnNewSelectedInterface) getActivity();
mListener2 = (ItemAdapter.OnNewsInsertedInterface) getActivity();
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeContainer);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
mManager = new LinearLayoutManager(getActivity());
mArticleAdapter = new ItemAdapter(getActivity(), new ArrayList<>(), mListener, mListener2);
if (!isNetworkAvailable()) alertUserAboutError();
mRecyclerView.setAdapter(mArticleAdapter);
mRecyclerView.setLayoutManager(mManager);
mSwipeRefreshLayout.setRefreshing(true);
new Downloader().execute(getUrl());
//new Downloader().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getUrl());
refreshData();
setDividerRecyclerView();
return view;
}
private void setDividerRecyclerView() {
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView
.getContext(), DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
}
private void alertUserAboutError() {
AlertDialogFragment alertDialogFragment = new AlertDialogFragment();
alertDialogFragment.show(getActivity().getFragmentManager(), "error_dialog");
}
protected abstract String[] getUrl();
private boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager)
getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}
private void refreshData() {
mSwipeRefreshLayout.setOnRefreshListener(() -> {
mArticleAdapter.clear();
new Downloader().execute(getUrl());
});
mSwipeRefreshLayout.setColorSchemeResources(
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
private class Downloader extends AsyncTask<String, Void, ArrayList<Article>> {
ArrayList<Article> mArticleArrayList = new ArrayList<>();
OkHttpClient mClient = new OkHttpClient();
@Override
protected ArrayList<Article> doInBackground(String... strings) {
for (String aMUrl : getUrl()) {
Request mRequest = new Request.Builder().url(aMUrl).build();
try {
Response response = mClient.newCall(mRequest).execute();
try {
if (response.isSuccessful()) {
String json = response.body().string();
mArticleArrayList = getMultipleUrls(json);
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return mArticleArrayList;
}
@Override
protected void onPostExecute(ArrayList<Article> articles) {
mArticleAdapter.addAll(articles);
mSwipeRefreshLayout.setRefreshing(false);
Log.v(TAAG, String.valueOf(mArticleAdapter.getItemCount()));
}
private ArrayList<Article> getMultipleUrls(String jsonData) throws JSONException {
if (mArticleArrayList == null || mArticleArrayList.size() == 0) {
mArticleArrayList = getArticleForecast(jsonData);
} else {
mArticleArrayList.addAll(getArticleForecast(jsonData));
}
return mArticleArrayList;
}
private ArrayList<Article> getArticleForecast(String jsonData) throws JSONException {
JSONObject forecast = new JSONObject(jsonData);
JSONArray articles = forecast.getJSONArray("articles");
ArrayList<Article> listArticles = new ArrayList<>(articles.length());
for (int i = 0; i < articles.length(); i++) {
JSONObject jsonArticle = articles.getJSONObject(i);
Article article = new Article();
String urlImage = jsonArticle.getString("urlToImage");
article.setTitle(jsonArticle.getString("title"));
article.setDescription(jsonArticle.getString("description"));
article.setImageView(urlImage);
article.setArticleUrl(jsonArticle.getString("url"));
article.setUrlToImage(jsonArticle.getString("urlToImage"));
listArticles.add(i, article);
}
return listArticles;
}
}
}
我在okhttp网站上也发现了这一点,但它也不起作用:
公共OkHttpClient.Builder sslSocketFactory(sslSocketFactory sslSocketFactory,
X509TrustManager(信任管理器)
设置用于保护HTTPS连接的套接字工厂和信任管理器。如果未设置,将使用系统默认值。
大多数应用程序不应该调用此方法,而是使用系统默认值。这些类包括特殊的优化,如果对实现进行修饰,这些优化可能会丢失
如有必要,您可以使用以下代码自己创建和配置默认值:
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { trustManager }, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustManager);
.build();
我的android应用程序(以及Spring Boot后端服务器)也有类似的问题。我认为您的问题与使用自签名证书有关。解决方案是在应用程序的资产文件夹中嵌入一个包含受信任证书的信任管理器(PKCS12格式) 1。将密钥库与证书一起添加到资产文件夹中: 2.然后用嵌入式信任管理器配置OkHttpClient,方法如下: (使用您的密码更改密码) 如果您想信任所有主机名,只需在
主机名验证程序
功能块中返回true,但我不建议您这样做,因为它会使您的应用程序面临安全威胁
请注意,使用自定义信任存储,您的应用程序将只信任该信任存储中包含的证书。我的android应用程序(以及我的Spring Boot后端服务器)也有类似问题。我认为您的问题与使用自签名证书有关。解决方案是在应用程序的资产文件夹中嵌入一个包含受信任证书的信任管理器(PKCS12格式) 1。将密钥库与证书一起添加到资产文件夹中: 2.然后用嵌入式信任管理器配置OkHttpClient,方法如下: (使用您的密码更改密码) 如果您想信任所有主机名,只需在
主机名验证程序
功能块中返回true,但我不建议您这样做,因为它会使您的应用程序面临安全威胁
请注意,使用自定义信任存储,您的应用程序将仅信任该信任存储中包含的证书。
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { trustManager }, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustManager);
.build();
fun getOkHttpClient(context: Context): OkHttpClient {
val password = "keystore_password".toCharArray()
val keyStore = KeyStore
.getInstance("PKCS12").apply {
load(context.assets.open("trust_store.p12"), password)
}
val trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm())
.apply { init(keyStore) }
val keyManagerFactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm())
.apply { init(keyStore, password) }
val sslContext = SSLContext.getInstance("SSL")
.apply {
init(keyManagerFactory.keyManagers, trustManagerFactory.trustManagers, SecureRandom())
}
return OkHttpClient.Builder()
.sslSocketFactory(sslContext.socketFactory,
trustManagerFactory.trustManagers[0] as X509TrustManager)
.hostnameVerifier { hostname, _ -> hostname == apiHostname } // Return true if you want to trust all hostnames
.build()
}