I am building an android app in Java for personal use, that would make use of the Dropbox api.
When I run a basic local unit test, I can make the simple call, that returns my username with the dropbox token. If however I try to run the same code in an Android emulator, I get the following exception:
java.lang.Class<com.android.org.conscrypt.OpenSSLSocketFactoryImpl> is not accessible from java.lang.Class<javax.net.ssl.SSLSocketFactory> Here is the activity code in Android
public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding; private Data data; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); binding.button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { testMe(view); } }); } private void testMe(View v){ String clientId = String.format("%s/%s", BuildConfig.APPLICATION_ID, BuildConfig.VERSION_NAME); DbxRequestConfig config = new DbxRequestConfig(clientId); DbxClientV2 client = new DbxClientV2(config,BuildConfig.dropboxToken); String s=""; try { s = client.users().getCurrentAccount().toString(); } catch (DbxException e) { e.printStackTrace(); } } } I have a very simple activity with one button which after I click, it is supposed to get my username from Dropbox, but when I click it, it throws the exception described above and crashes.
My build.gradle is:
plugins { id 'com.android.application' } android { namespace 'com.daresunny.librebudget' compileSdk 34 defaultConfig { applicationId "com.daresunny.librebudget" android.buildFeatures.buildConfig true minSdk 28 targetSdk 34 versionCode 1 versionName "1.0" Properties localProperties = getLocalProperties() String dropboxKey = localProperties['DROPBOX_APP_KEY'] String secretToken = localProperties['DROPBOX_APP_TOKEN'] if (dropboxKey == null) { dropboxKey = "missingApiKey" logger.warn("No value provided for DROPBOX_APP_KEY. Specify a value in a examples/android/local.properties file. You can register for one at https://developers.dropbox.com/") } buildConfigField "String","dropboxAPIKey", "\"${dropboxKey}\"" buildConfigField "String","dropboxToken", "\"${secretToken}\"" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } buildFeatures { viewBinding true } } dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'org.bouncycastle:bcpkix-jdk15on:1.67' implementation 'com.google.android.material:material:1.11.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'com.dropbox.core:dropbox-android-sdk:6.0.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:5.4.0' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' } def getLocalProperties() { Properties props = new Properties() if (file('local.properties').exists()) { props.load(new FileInputStream(file('local.properties'))) } return props } My Android Manifest is:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <application android:requestLegacyExternalStorage="true" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Librebudget" tools:targetApi="28"> <activity android:name=".gui.MainActivity" android:exported="true" android:label="@string/title_activity_main" android:theme="@style/Theme.Librebudget.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> And If it is of any relevance, I am using Android studio on Linux.
I would be grateful if anyone knows what can be causing this exception. It seems to be somehow related to the Android emulator, since the same test works perfectly fine outside of the android environment.
Edit:
It seems to me that it has something to do with the https requests that the dropbox api relies on. I get the same exception, when I try to just ping Wikipedia as shown in the example:
https://developer.android.com/privacy-and-security/security-ssl#java
The exception gets thrown by the method SocketFactor.getDefault(). Has it something to do with an SSL api, that is just not present on the emulator? If so can it be changed to an alternative one, at least while I test my application?