Adjust user agent in Android with Volley - android

I am wondering how to adjust the standard user agent in my http requests. I am using the Volley library and I KNOW how to
set a new user agent
retrieve the default user agent as a string (e.g. "Dalvik/1.6.0 (Linux; U; Android 4.0.2; sdk Build/ICS_MR0") => System.getProperty("http.agent")
What I DON'T know is:
how to get the single elements this user agent is build of, so I can replace only the string "Dalvik/1.6.0" with a custom string.
Is that possible, or do I have to make a string replacement?
Thx

In order to set the user agent globally for all requests sent via volley, here is my solution:
When you are initializing the volley request queue, instead of using the convenient method Volley.newRequestQueue(Context);, use the following snippet:
private RequestQueue makeRequestQueue(Context context) {
DiskBasedCache cache = new DiskBasedCache(new File(context.getCacheDir(), DEFAULT_CACHE_DIR), DISK_CACHE_SIZE);
BasicNetwork network = new BasicNetwork(new MyHurlStack());
RequestQueue queue = new RequestQueue(cache, network);
queue.start();
return queue;
}
public static class MyHurlStack extends HurlStack {
#Override
public HttpResponse executeRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError {
if (additionalHeaders == null || Collections.emptyMap().equals(additionalHeaders) {
additionalHeaders = new HashMap<>();
}
additionalHeaders.put("User-Agent", "test_user_agent_in_volley");
return super.executeRequest(request, additionalHeaders);
}
}
This solution assumes you are targeting api level >= 9, so we use the HurlStack
The reason why this works is because in HurlStack.executeRequest(Request<?> request, Map<String, String> additionalHeaders) method, the stuff you add to the additionalHeaders would later be added to an HttpUrlConnection request property as in connection.addRequestProperty(headerName, map.get(headerName));

Yes,
Build.FINGERPRINT contains all the information you need,
https://developer.android.com/reference/android/os/Build.html
To get the individual parts, use the individual constant strings,
For detailed OS Version information use Build.VERSION
import android.util.Log;
import android.os.Bundle;
import android.os.Build;
public class MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("Build","BOARD = "+Build.BOARD);
Log.i("Build","BOOTLOADER = "+Build.BOOTLOADER);
Log.i("Build","BRAND = "+Build.BRAND);
Log.i("Build","CPU_ABI = "+Build.CPU_ABI);
Log.i("Build","CPU_ABI2 = "+Build.CPU_ABI2);
Log.i("Build","DEVICE = "+Build.DEVICE);
Log.i("Build","DISPLAY = "+Build.DISPLAY);
Log.i("Build","FINGERPRINT = "+Build.FINGERPRINT);
Log.i("Build","HARDWARE = "+Build.HARDWARE);
Log.i("Build","HOST = "+Build.HOST);
Log.i("Build","ID = "+Build.ID);
Log.i("Build","MANUFACTURER = "+Build.MANUFACTURER);
Log.i("Build","MODEL = "+Build.MODEL);
Log.i("Build","PRODUCT = "+Build.PRODUCT);
Log.i("Build","RADIO = "+Build.RADIO);
Log.i("Build","SERIAL = "+Build.SERIAL);
Log.i("Build","TAGS = "+Build.TAGS);
Log.i("Build","TYPE = "+Build.TYPE);
Log.i("Build","USER = "+Build.USER);
Log.i("Build","BASE_OS = "+Build.VERSION.BASE_OS);
Log.i("Build","CODENAME = "+ Build.VERSION.CODENAME);
Log.i("Build","INCREMENTAL = "+ Build.VERSION.INCREMENTAL);
Log.i("Build","RELEASE = "+ Build.VERSION.RELEASE);
Log.i("Build","SDK = "+ Build.VERSION.SDK);
Log.i("Build","SECURITY_PATCH = "+ Build.VERSION.SECURITY_PATCH);
Log.i("$TAG#",Build.FINGERPRINT);
}
}

System.getProperty("http.agent") returns something like:
Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)
It's possible to build all the parts of this using a combination of android.os.Build and java.lang.System.getProperty().
This is an example of what's in android.os.Build running on an emulator:
Build.BOARD = "goldfish_x86"
Build.BOOTLOADER = "unknown"
Build.BRAND = "google"
Build.DEVICE = "generic_x86"
Build.DISPLAY = "sdk_gphone_x86-userdebug 9 PSR1.180720.075 5124027 dev-keys"
Build.FINGERPRINT = "google/sdk_gphone_x86/generic_x86:9/PSR1.180720.075/5124027:userdebug/dev-keys"
Build.HARDWARE = "ranchu"
Build.HOST = "abfarm904"
Build.ID = "PSR1.180720.075"
Build.MANUFACTURER = "Google"
Build.MODEL = "Android SDK built for x86"
Build.PRODUCT = "sdk_gphone_x86"
Build.SUPPORTED_32_BIT_ABIS = {"x86"}
Build.SUPPORTED_64_BIT_ABIS = {}
Build.SUPPORTED_ABIS = {"x86"}
Build.TAGS = "dev-keys"
Build.TIME = 1541887073000
Build.TYPE = "userdebug"
Build.USER = "android-build"
Build.UNKNOWN = "unknown"
Build.VERSION.BASE_OS = ""
Build.VERSION.CODENAME = "REL"
Build.VERSION.INCREMENTAL = "5124027"
Build.VERSION.PREVIEW_SDK_INT = 0
Build.VERSION.RELEASE = "9"
Build.VERSION.SDK_INT = 28
Build.VERSION.SECURITY_PATCH = "2018-09-05"
These properties are always provided by the Dalvik VM, according to Google's documentation:
file.separator = /
java.class.path = .
java.class.version = 50.0
java.compiler = Empty
java.ext.dirs = Empty
java.home = /system
java.io.tmpdir = /sdcard
java.library.path = /vendor/lib:/system/lib
java.vendor = The Android Project
java.vendor.url = http://www.android.com/
java.version = 0
java.specification.version = 0.9
java.specification.vendor = The Android Project
java.specification.name = Dalvik Core Library
java.vm.version = 1.2.0
java.vm.vendor = The Android Project
java.vm.name = Dalvik
java.vm.specification.version = 0.9
java.vm.specification.vendor = The Android Project
java.vm.specification.name = Dalvik Virtual Machine Specification
line.separator = \n
os.arch = armv7l
os.name = Linux
os.version = 2.6.32.9-g103d848
path.separator = :
user.dir = /
user.home = Empty
user.name = Empty
So, the default user agent appears to be composed of:
System.getProperty("java.vm.name") // Dalvik
System.getProperty("java.vm.version") // 2.1.0
System.getProperty("os.name") // Linux
"U" // not sure where to get this
"Android" // or this, probably safe to hard code though
Build.VERSION.RELEASE // 9
Build.MODEL // Android SDK built for x86
Build.ID // PSR1.180720.075

Related

Add 802.1x suggested network

I am trying to add an 802.1x network as a suggested network in Android 10.
When I do the addSuggestedNetwork it returns a code of 0 indicating that it did add it.
I even checked it by trying to add a second time. That returned 3 - network already exists.
Nevertheless, it doesn't fill in any of the parameters of the AP definition:
WifiManager wifiManager = getSystemService(Context.WIFI_SERVICE));
WifiNetworkSuggestion.Builder suggestionBuilder = new WifiNetworkSuggestion.Builder();
String ssid = c8021XAP.getSsid();
WifiNetworkSuggestion suggestion = suggestionBuilder
.setSsid(ssid)
.setWpa3EnterpriseConfig(c8021XAP.eapConfig())
.setPriority(10)
.build();
List<WifiNetworkSuggestion> suggestions = new ArrayList<>();
status = wifiManager.addNetworkSuggestions(suggestions);
Following is the code that creates the eapConfig object:
fun eapConfig(): WifiEnterpriseConfig {
val eap = WifiEnterpriseConfig()
eap.identity = username
eap.password = Base64.encode(password.toByteArray(), Base64.DEFAULT).toString()
eap.anonymousIdentity = anonymousIdentity
eap.phase2Method = phase2
eap.eapMethod = eapMethod
eap.domainSuffixMatch = domainName
return eap
}
I tried changing setWpa3EnterpriseConfig to setWpa2EnterpriseConfig but no change.

Add 802.1x network in Android 10+

I am trying to add a 802.1x network programmatically in my Android app.
On an Android 8 device using addNetwork I see that the network is added with credentials but on Android 10 and above, when using addNetworkSuggestions, the credentials are not added.
I am new in this field so it is possible I am missing something vital.
WifiConfiguration wifiConf = new WifiConfiguration();
wifiConf.allowedAuthAlgorithms.clear();
wifiConf.allowedGroupCiphers.clear();
wifiConf.allowedKeyManagement.clear();
wifiConf.allowedPairwiseCiphers.clear();
wifiConf.allowedProtocols.clear();
wifiConf.SSID = TextUtil.convertToQuotedString(apSsid.toString());
wifiConf.enterpriseConfig = eapConfig.asWifiEnterpriseConfig();
wifiConf.enterpriseConfig.setIdentity(......);
wifiConf.enterpriseConfig.setPassword(......);
wifiConf.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
wifiConf.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wifiConfig.status = WifiConfiguration.Status.ENABLED;
wifiConfig.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
wifiConfig.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
wifiConf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wifiConf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wifiConf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wifiConf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
if (apPass.length() == 64 && WeFiUtilExt.isHex(apPass)) {
// Goes unquoted as hex
wifiConf.preSharedKey = apPass;
}
else {
// Goes quoted as ASCII
wifiConf.preSharedKey = TextUtil.convertToQuotedString(apPass);
}
WifiNetworkSuggestion.Builder wpa2WifiNetworkSuggestionBuilder = new WifiNetworkSuggestion.Builder();
wpa2WifiNetworkSuggestionBuilder.setSsid(ssid).setIsAppInteractionRequired(true);
wpa2WifiNetworkSuggestionBuilder.setWpa2EnterpriseConfig(wifiEnterpriseConfig);
WifiNetworkSuggestion wpa2WifiNetworkSuggestion = wpa2WifiNetworkSuggestionBuilder.build();
WifiNetworkSuggestion.Builder wpa3WifiNetworkSuggestionBuilder = new WifiNetworkSuggestion.Builder();
wpa3WifiNetworkSuggestionBuilder.setSsid(ssid).setIsAppInteractionRequired(false);
wpa3WifiNetworkSuggestionBuilder.setWpa3EnterpriseConfig(wifiEnterpriseConfig);
WifiNetworkSuggestion wpa3WifiNetworkSuggestion = wpa3WifiNetworkSuggestionBuilder.build();
List<WifiNetworkSuggestion> wifiNetworkSuggestionList = new ArrayList<>();
wifiNetworkSuggestionList.add(wpa2WifiNetworkSuggestion);
wifiNetworkSuggestionList.add(wpa3WifiNetworkSuggestion);
int addStatus = m_wifiMngr.addNetworkSuggestions(wifiNetworkSuggestionList);
The return code is 0 implying that the add worked.
Will this not work in Android 10+?

Creating Notes in LinkedNotebook

I am trying to create note in a shared notebook which is already shared with me. The notebook is shared with me with priveleges to modify its contents (SharedNotebookPrivilegeLevel.MODIFY_NOTEBOOK_PLUS_ACTIVITY), and I can create notes in that notebook using Evernote web client. But when I trying to create a note using SDK I received an EDAMUserException(errorCode:PERMISSION_DENIED, parameter:authenticationToken). Below is my code
Note note = new Note();
note.setContent(EvernoteUtil.NOTE_PREFIX + content + EvernoteUtil.NOTE_SUFFIX);
note.setTitle(title);
EvernoteSession evernoteSession = EvernoteSession.getInstance();
List<LinkedNotebook> linkedNotebooks = evernoteSession
.getEvernoteClientFactory()
.getNoteStoreClient()
.listLinkedNotebooks();
LinkedNotebook current = null;
for (LinkedNotebook linkedNotebook : linkedNotebooks) {
if (linkedNotebook.getShareName().equals(notebookName)) {
current = linkedNotebook;
}
}
if (current == null)
throw new IllegalStateException();
THttpClient tHttpClient = new THttpClient(current.getNoteStoreUrl());
TBinaryProtocol tBinaryProtocol = new TBinaryProtocol(tHttpClient);
NoteStore.Client client = new NoteStore.Client(tBinaryProtocol, tBinaryProtocol);
AuthenticationResult authenticationResult = client.authenticateToSharedNotebook(current.getShareKey(),
evernoteSession.getAuthToken());
String shareToken = authenticationResult.getAuthenticationToken();
SharedNotebook sharedNotebook = client.getSharedNotebookByAuth(shareToken);
String sharedNotebookGuid = sharedNotebook.getNotebookGuid();
note.setGuid(sharedNotebookGuid);
Note createdNote = client.createNote(shareToken, note);
return createdNote;
I've used this article to create notes.
One mistake I found is that
note.setGuid(sharedNotebookGuid);
has to be
note.setNotebookGuid(sharedNotebookGuid);

Web Audio Api biquadFilter in Android needs extra configuration?

Here says the Web audio API works in Chrome for Android, and here I have tested CM Browser, Chrome and CyanogenMod default Android 5.1.1 browsers, and all pass the tests (specially the biquadNode one).
But When I open this codepen with an eq (biquadNode), I can hear the music but not the eq working.
Does biquadNode works in android? any special implementation is needed?
*Code pen required to post
var context = new AudioContext();
var mediaElement = document.getElementById('player');
var sourceNode = context.createMediaElementSource(mediaElement);
// EQ Properties
//
var gainDb = -40.0;
var bandSplit = [360,3600];
var hBand = context.createBiquadFilter();
hBand.type = "lowshelf";
hBand.frequency.value = bandSplit[0];
hBand.gain.value = gainDb;
var hInvert = context.createGain();
hInvert.gain.value = -1.0;
var mBand = context.createGain();
var lBand = context.createBiquadFilter();
lBand.type = "highshelf";
lBand.frequency.value = bandSplit[1];
lBand.gain.value = gainDb;
var lInvert = context.createGain();
lInvert.gain.value = -1.0;
sourceNode.connect(lBand);
sourceNode.connect(mBand);
sourceNode.connect(hBand);
hBand.connect(hInvert);
lBand.connect(lInvert);
hInvert.connect(mBand);
lInvert.connect(mBand);
var lGain = context.createGain();
var mGain = context.createGain();
var hGain = context.createGain();
lBand.connect(lGain);
mBand.connect(mGain);
hBand.connect(hGain);
var sum = context.createGain();
lGain.connect(sum);
mGain.connect(sum);
hGain.connect(sum);
sum.connect(context.destination);
// Input
//
function changeGain(string,type)
{
var value = parseFloat(string) / 100.0;
switch(type)
{
case 'lowGain': lGain.gain.value = value; break;
case 'midGain': mGain.gain.value = value; break;
case 'highGain': hGain.gain.value = value; break;
}
}
createMediaElementSource in Chrome on Android doesn't work in general. But if you have a recent build of Chrome (49 and later?), you can go to chrome://flags and enable the unified media pipeline option. That will make createMediaElementSource work like on desktop.

libSpotify is crashing in Android

I'm doing an app that requires Spotify in Android. But when i run libSpotify "sp_session_create" i get a SIGSEGV. The version of libSpotify that i'm using is v12.1.51 BETA - For android ARM
sp_error initialise(const char * asKey,
const char * asFolder,
const char * asUserAgent,
bool isPlaylistCompressed,
bool isMetadataOnPlaylist,
bool isPlaylistInitialUnload)
{
sp_session_callbacks asCallbacks;
memset(&asCallbacks, 0, sizeof(asCallbacks));
asCallbacks.logged_in = Callback::onSessionLogin;
asCallbacks.log_message = Callback::onSessionLog;
sp_session_config asConfiguration;
memset(&asConfiguration, 0, sizeof(asConfiguration));
std::string asDirectory = asFolder;
auto asDirectoryCache = asDirectory + "/cache";
auto asDirectorySetting = asDirectory + "/setting";
const auto asApplicationKey = "Key goes here...";
asConfiguration.api_version = SPOTIFY_API_VERSION;
asConfiguration.application_key = asApplicationKey;
asConfiguration.application_key_size = sizeof(asApplicationKey);
asConfiguration.cache_location = asDirectoryCache.c_str();
asConfiguration.settings_location = asDirectorySetting.c_str();
asConfiguration.user_agent = asUserAgent;
asConfiguration.compress_playlists = isPlaylistCompressed;
asConfiguration.dont_save_metadata_for_playlists = isMetadataOnPlaylist;
asConfiguration.initially_unload_playlists = isPlaylistInitialUnload;
asConfiguration.userdata = this;
asConfiguration.callbacks = &asCallbacks;
sp_error asError = sp_session_create(&asConfiguration, &_asSession);
__android_log_print(ANDROID_LOG_VERBOSE, LIBRARY_NAME, "PASSED");
return asError;
}
The crash was due to cache folder.
Edit: Spotify's new Android SDK is released! You should strongly consider moving your project to the new SDK, since libspotify is now deprecated for that platform.

Categories

Resources