Huawei Honor 10 blocked Bluetooth when app is running - java

I`m development network radio app for Android API 21-29 and all worked fine but one cases confuses me. On Huawei Honor 10 when my app started playing and trying to switch on the Bluetooth nothing works. Device turn-off Bluetooth and all. I add this permission in my AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
If Bluetooth turn on before playing, he turn off right after start play.
I used this method when app send mediasession.OnPlay
#Override
public void onPlay() {
if (!exoPlayer.getPlayWhenReady()) {
startService(new Intent(getApplicationContext(), PlayerService.class));
if (stationsRepository == null)
return;
station = stationsRepository.getCurrent();
bitrate = Connectivity.currentBitrate;
String stream = station.getStreamByBitrate(bitrate);
prepareToPlay(Uri.parse(stream));
mediaSession.setQueueTitle(station.getTitle());
if (!audioFocusRequested) {
audioFocusRequested = true;
int audioFocusResult;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
audioFocusResult = audioManager.requestAudioFocus(audioFocusRequest);
} else {
audioFocusResult = audioManager.requestAudioFocus(audioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
if (audioFocusResult != AudioManager.AUDIOFOCUS_REQUEST_GRANTED)
return;
}
mediaSession.setActive(true);
registerReceiver(becomingNoisyReceiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
exoPlayer.setPlayWhenReady(true);
}
mediaSession.setPlaybackState(stateBuilder.setState(PlaybackStateCompat.STATE_PLAYING, PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN, 1).build());
currentState = PlaybackStateCompat.STATE_PLAYING;
refreshNotificationAndForegroundStatus(currentState);
}
On same devices uses Android 10, Android 8, Android 7 all work is fine.
Can anyone help me fix with this.
P.S. Sorry for my English. This is the first time when I ask a question in this language.
Update: Tested on Huawei P30 lite and catch this bug too.

Related

Android - Download Unsuccessful and Parsing Error while trying to download and install .apk from server

The goal is to update my app without using the google play store. I’m trying to download a .apk file from a server and then install it programmatically. I’m currently getting an error that the download is unsuccessful and that there was an error while parsing the package. I have the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions requested at runtime. I had to go into the tablet's settings to give permission to “Install unknown apps”. I cannot get REQUEST_INSTALL_PACKAGES to be requested at runtime.
If I change the fileName and update URL to get a .txt that I store in the same folder on the server as the .apk AND comment out “.setMimeType()” I can download and view a .txt file.
Have the updates to Android Studio made older tutorials or examples of this outdated?
Is there a new or better way to download .apk’s from servers programmatically?
Is the lack of REQUEST_INSTALL_PACKAGES permission at runtime what is preventing my .apk from downloading?
Any advice on how to fix my code?
Here are some code snippets to help
gradle:app
android {
compileSdk 31
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "farrpro.project"
minSdk 28
targetSdk 30
}
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.ACTION_INSTALL_PACKAGE"/>
MainActivity.java
private void hasInstallPermission() { // runs in onCreate()
if (getApplicationContext().checkSelfPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 1);
}
}
void downloadAndInstallUpdate(){ // runs when users accepts request to download update
String fileName = "update.apk";
// example of update’s string
update = “https://myserver.net/update.apk”;
//set download manager
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(update));
request.setTitle(fileName)
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setDescription("Downloading")
//.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
.setMimeType("application/vnd.android.package-archive");
// get download service and enqueue file
final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
final long downloadId = manager.enqueue(request);
System.out.println("Max Bytes: "+DownloadManager.getMaxBytesOverMobile(this)); //returns null
//set BroadcastReceiver to install app when .apk is downloaded
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
System.out.println("Is download successful: "+ manager.getUriForDownloadedFile(downloadId)); //returns null
System.out.println("Mime: "+manager.getMimeTypeForDownloadedFile(downloadId)); //returns application/vnd.android.package-archive
Intent install = new Intent(Intent.ACTION_VIEW);
File file = new File(ctxt.getExternalFilesDir(null) + fileName);
Uri downloadedApk = FileProvider.getUriForFile(ctxt, "farrpro.project.provider", file);
install.setDataAndType(downloadedApk,
manager.getMimeTypeForDownloadedFile(downloadId));
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
startActivity(install);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Log.e("TAG", "Error in opening the file!");// this never prints
}
unregisterReceiver(this);
finish();
}
};
//register receiver for when .apk download is complete
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
The problem was the server had restricted download types. My code worked more or less after that setting was changed. I ended up needing to change the intents in my broadcast receiver so that after the download was completed the new .apk would immediately install. Here are the changes I made to make the code posted work.
final long downloadId = manager.enqueue(request);
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent1) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(manager.getUriForDownloadedFile(downloadId), "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
getApplicationContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Log.e("TAG", "Error in opening the file!");
}
unregisterReceiver(this);
finish();
}
};
If your app is running on Android O or newer, you have to allow unknown app sources for your app.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!context.packageManager.canRequestPackageInstalls()) {
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).apply {
data = Uri.parse(String.format("package:%s", context.packageName))
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(intent)
}
}

Android Studio Java Bluetooth LE doesn't work

So I have my Arduino advertising BLE, I can download, "BLE Scanner" app to connect to it and it works that way. Now I'm writing app on Android to connect to that Arduino. I've got following code but it doesn't work:
ScanCallback scanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, final ScanResult result) {
super.onScanResult(callbackType, result);
System.out.println("Callback: " + callbackType);
}
#Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
System.out.println("callback error");
}
};
BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
BluetoothLeScanner mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
ScanSettings scanSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
mLEScanner.startScan(null,scanSettings,scanCallback);
and I'm getting this error:
I/BNRClientProivder, VERSION : 1.7.5: register - xml6 quick_backup : ACCESSIBILITYSETTINGS, X6qErjsfs2, com.android.settings.accessibility.sharedaccessibility.scloud.BNRTask
I/QBNRClientHelper: init SyncClientHelper : ACCESSIBILITYSETTINGS
I/BNRClientProivder, VERSION : 1.7.5: register - xml6 quick_backup : CONNECTIONS, C0phMaUuZZ, com.android.settings.wifi.mobileap.WifiApBackupRestore
I/QBNRClientHelper: init SyncClientHelper : CONNECTIONS
I/BNRClientProivder, VERSION : 1.7.5: register - xml6 quick_backup : WiFi, C0phMaUuZZ, com.android.settings.wifi.WifiBackupRestore
Accessibility settings seems like permissions. You need to allow for ble features within the application.
Go to your manifest file add bluetooth permissions and location permissions
Then you will need to grant the app permissions when you run it. Go to your open apps and press the 3 dots, app info, permissions location enable.
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Also I cant see what the scan result it. On a ble scan callback you get the device address, scan record(advert data) and the rssi(power received).

How to turn on location in order to display found bluetooth device

I am trying to do a indoor location services using bluetooth LE scan to search for beacons. However, in order to display found bluetooth devices, location need to be turned on.
I tried searching online for solutions but to no avail. I have only enable the permission for the app not to turn on the location.
this is the code for the permission
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect peripherals.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
i have also added the permission in android manifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

BluetoothAdapter.getBondedDevices returns zero Devices although paired, why?

I'm currently trying to write an Android App which connects to a Device using Bluetooth and opens a serial connection. To connect to the device I need to pass the device to some Code which establishes and maintains the connection. My Problem is that I don't seem to get to this point because my code always returns a NullPointer as device.
I've already tried debugging the code and now found out that the function to get bonded devices returns zero devices. To mitigate this I've made sure that the bluetooth adapter is existent and is turned on. I've also made sure in the android menu that there are devices connected and that the android device I want to establish a connection to has been paired with.
Below is the code which should identify and return the device:
public class BluetoothDeviceRecognition {
BluetoothDevice blDevice(BluetoothAdapter myBluetoothAdapter) {
Set<BluetoothDevice> pairedDevices = myBluetoothAdapter.getBondedDevices();
BluetoothDevice myDevice = null;
if(pairedDevices.size() > 0){
for (BluetoothDevice device : pairedDevices){
if (device.getName().equals("ESP32_LED_Control")) {
myDevice = device;
}
}
}
return myDevice;
}
This is the Code which should make sure that there is a bluetooth adapter and which should enable it if this is not the case:
public void startBluetooth(){
if(mBluetoothAdapter == null)
{
Log.d(TAG, "connectBluetooth: Does not have Bluetooth Capabilities");
return;
}
if(!mBluetoothAdapter.isEnabled())
{
Log.d(TAG, "connectBluetooth: Enabling Bluetooth");
Intent enableBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBTIntent);
}
}
And this is the code which starts the code above:
connect.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try{
startBluetooth();
BluetoothDevice myDevice = mBluetoothDevice.blDevice(mBluetoothAdapter);
connectBluetooth(myDevice, MY_UUID_INSECURE);
}
catch(NullPointerException e){
Log.d(TAG, "connectBluetooth: Bluetooth Device cannot be Null");
sent.setText("Error, Bluetooth Device cannot be Null");
}
}
});
When setting a break point at the beginning of the if loop in the first code snippet, I expect to have the size of the pairedDevices be greater than 0 but the actual size of the pairedDevices is zero.
EDIT:
My Manifest File:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application
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/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
My Target SDK should be 21.
EDIT:
So I didn't really solve this but instead used a different approach. Instead of looking for devices which were paired with my device I am instead looking for devices which are currently discoverable near me. Used this code: https://github.com/mitchtabian/Sending-and-Receiving-Data-with-Bluetooth
Before calling mBluetoothDevice.blDevice(mBluetoothAdapter), you must make sure that bluetooth has been turned on. So you just need to use startActivityForResult(enableBTIntent) to enable bluetooth and receive the result from onActivityResult(), once you receive the reslut that user turns on bluetooth, you can call mBluetoothDevice.blDevice(mBluetoothAdapter).
You are Missing The Location Permission,
As Stated in the Documentation :
https://developer.android.com/guide/topics/connectivity/bluetooth#Permissions
If your target Sdk is 23 and higher, you should ask for this Permission at runtime

Android No Activity found - STILL_IMAGE_CAMERA

I am getting the following exception in my android app.
No Activity found to handle Intent { act=android.media.action.STILL_IMAGE_CAMERA (has extras) }
I know that my device, an MC70, has a camera.
bool hasFeature = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA);
int numCameras = android.hardware.Camera.getNumberOfCameras();
Both hasFeature is true and numCameras > 0
The device has an SD card installed:
Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
In the AndroidManifest.xml file I have:
<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-permission android:name="android.permission.CAMERA" />
final PackageManager packageManager = context.getPackageManager();
This list comes back empty, probably a bad sign:
final Intent intent = new Intent(action);
List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
This code must run on the MC70, which is limited to KitKat 4 API 19.
But when I call:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent, 1);
I get the exception:
No Activity found to handle Intent { act=android.media.action.STILL_IMAGE_CAMERA_SECURE (has extras) }
I have tried:
MediaStore.ACTION_IMAGE_CAPTURE
MediaStore.ACTION_IMAGE_CAPTURE_SECURE
MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA
MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE
All throw the exception. Why?
Why?
Because the device manufacturer did not install a camera app that supports any of those Intent structures. If the device does not legitimately ship with the Play Store on it, there is no requirement that the manufacturer have to meet any particular compatibility requirements.
Assuming that you do not need a camera app with any particular features, install an open source one, like Open Camera, so your device has an app that responds to ACTION_IMAGE_CAPTURE, etc.

Categories

Resources