In android i want to open android notification quick setting in android program after a lot of searching from all resources found code for opening notification bar only.
Note that this code relies on non-public API's. It is not guaranteed to run correctly on all Android devices.
try {
Object service = getSystemService("statusbar");
Class<?> statusBarManager = Class.forName("android.app.StatusBarManager");
// expands the notification bar into the quick settings mode
// - replace expandSettingsPanel with expandNotificationsPanel
// if you just want the normal notifications panel shown
Method expand = statusBarManager.getMethod("expandSettingsPanel");
expand.invoke(service);
} catch (Exception e) {
// do something else
}
Don't forget the required manifest permission:
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
Related
I've been trying to get my app to be able to delete an audio file. However, after trying many possible solutions, I couldn't really find one that works.
Here is my solution so far:
public static void deleteFiles(List<Track> tracks, Context context,
final MutableLiveData<IntentSender> deletionIntentSenderLD){
final Uri AUDIO_URI = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
for(Track t : tracks){
try {
context.getContentResolver().delete(ContentUris
.withAppendedId(AUDIO_URI, t.getUriId()), null, null);
}catch (SecurityException securityException) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (securityException instanceof RecoverableSecurityException) {
deletionIntentSenderLD
.postValue(((RecoverableSecurityException) securityException)
.getUserAction().getActionIntent().getIntentSender());
} else
throw securityException;
} else
throw securityException;
}
}
}
When the try block fails a SecurityException is catch then the IntentSender is passed to the live data that is observed in a fragment:
audioViewModel.getDeletionIntentSenderLD().observe(getViewLifecycleOwner(),
intentSender -> {
try {
startIntentSenderForResult(intentSender, DELETE_PERMISSION_REQUEST,
null, 0 ,0, 0,
null);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
});
I've tried implementing the onRequestPermissionResult() method but that doesn't do anything. I've also tried deleting the files using File file = new File(), however, due to the changes made to Android 10, I didn't expect it to work.
So after many Google searches, I've come to the conclusion that the best approach (to my knowledge) is to simply turn off scoped storage for Android Q (10).
Here, I'll provide two solutions. The first is the one where I turn it off and the second is the one where scope storage is still enable. However, a thing you should note is that the second solution is a little buggy, at times it actually does delete both the actual media file and updates the Media Store, but most times it simply deletes from the Media Store only. Obviously, this isn't a very good solution as on reboot your application would then load those files back in because the Media Store would scan for them.
Solution 1 - Turn off Scoped Storage
For this solution you can still target Android 11. All you have to do is go to the build.gradle file at the Module Level and set the compileSdkVersion and targetSdkVersion to 30.
After that, you go into the AndroidManifest.xml and have the uses-permission and application tag set up like this:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"
tools:ignore="ScopedStorage"/>
<application
android:requestLegacyExternalStorage="true"
...
After having done that, you could use the Content Resolver to delete the media file (and update the Media Store) and you do not have to worry about catching a security exception like its said in the Android docs. Your implementation for Android 11s delete operation should not be affected.
Solution-ish 2 - Turn on Scoped Storage
Firstly, in your manifest ensure that the WRITE_EXTERNAL_STORAGE permissions maxSdkVersion is set to 28. Also ensure that requestLegacyExternalStorage is set to false (don't think this is required). Then simply copy the code in my original post. You do not require a Live Data if you are doing the delete operation from your activity/fragment. But you should note that startIntentSenderForResult() requires an activity.
But as I mentioned before, I did experience some bugs with this. The most frustrating thing about this solution though is that it does not delete the actual file but instead deletes the entry from the Media Store. Maybe this has something to do with the fact that #blackapps mentioned, which is that you cannot bulk delete and I might have implemented it slightly wrong. Nevertheless, this is horrible for user experience if bulk deletion is impossible in Android 10.
The tutorials I followed for this are:
https://developer.android.com/training/data-storage/shared/media#remove-item
https://www.raywenderlich.com/9577211-scoped-storage-in-android-10-getting-started#toc-anchor-007
https://www.solutionanalysts.com/blog/scoped-storage-in-android-10/
Side Note - Delete on Android 11
To delete on Android 11 you just need to call createDeleteRequest() which should return a PendingIntent. From this PendingIntent you could get the IntentSender by using getIntentSender. Pass this intent sender to the activity/fragment then call startIntentSenderForResult() in your activity/fragment. This pops up a dialog to the user asking them if the application can delete a file. If the user gives permission the system goes ahead and deletes the file and updates the Media Store.
Side Side Note - Scoped Storage, Android 10 and Future
From everything I've seen, it seems to suggest that scoped storage is only enforced in Android 11 but I'm not entirely sure if the legacy option would still be available in Android 10 indefinitely. But I would have to do more research on this...
Why isOperational() in mobile vision text recognizer returns false?
At first, mobile vision only show preview camera and after many tries to get the result, I saw that the texts recognized but in one device it works and in other device does not.
What should I do?
For example, in one device, isOperational() returns false, and it goes to readstate() and after that goes to looper() and stays on it!
in other device it only return false and doesn't go to looper.
I want ask other questions about it:
My first question is: how does isOperational() work? I can't understand it.
Maybe it goes to looper to download the native library in a queue and after many try, at last download completes and work. Can it be correct? Or is it just a bug that it goes to looper? Anywhere, what should I do?
Can I work on this when it works in one device I tried and in other does not? Or it must work in every device to I can work on it? And I get .apk from project but it can't install in devices, why?
Should it check for network?
Should it check for access to the memory?
note: it works with camera API and its deprecated. maybe the problem is with this!
TextRecognizer textRecognizer = new TextRecognizer.Builder(context).build();
textRecognizer.setProcessor(new OcrDetectorProcessor(graphicOverlay));
if (!textRecognizer.**isOperational**()) {
// Note: The first time that an app using a Vision API is installed on a
// device, GMS will download a native libraries to the device in order to do detection.
// Usually this completes before the app is run for the first time. But if that
// download has not yet completed, then the above call will not detect any text,
// barcodes, or faces.
//
// isOperational() can be used to check if the required native libraries are currently
// available. The detectors will automatically become operational once the library
// downloads complete on device.
Log.w(TAG, "Detector dependencies are not yet available.");
// Check for low storage. If there is low storage, the native library will not be
// downloaded, so detection will not become operational.*
IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
boolean hasLowStorage = registerReceiver(null, lowstorageFilter) != null;
if (hasLowStorage) {
Toast.makeText(this, R.string.low_storage_error, Toast.LENGTH_LONG).show();
Log.w(TAG, getString(R.string.low_storage_error));
}
}
*// Creates and starts the camera. Note that this uses a higher resolution in comparison
// to other detection examples to enable the text recognizer to detect small pieces of text.*
cameraSource =
new CameraSource.Builder(getApplicationContext(), textRecognizer)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(1280, 1024)
.setRequestedFps(2.0f)
.setFlashMode(useFlash ? Camera.Parameters.FLASH_MODE_TORCH : null)
.setFocusMode(autoFocus ? Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO : null)
.build();
}
It doesn't produce any error and show preview camera but doesn't recognize texts in some devices.
I'm trying to develop a simple camera app with face detection and i'm using android-vision sample from here
https://github.com/googlesamples/android-vision/tree/master/visionSamples/FaceTracker
Everything is working fine and i need to add zoom in/out feature in it. I searched SO but found nothing related to vision. Every answer is related to Camera2.
You might try startSmoothZoom:
https://developer.android.com/reference/android/hardware/Camera.html#startSmoothZoom(int)
You'd need to modify the open source version of CameraSource to make this change, since you'd need access to its underlying android.hardware.Camera instance:
https://github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ui/camera/CameraSource.java#L121
Try this code, it works (Yes, it's reflection)
try {
cameraSource.apply {
start(holder)
javaClass.getDeclaredField("zzg").apply {
isAccessible = true
(get(cameraSource) as Camera).apply {
startSmoothZoom(min(5, parameters.maxZoom))
}
}
}
} catch (e: Throwable) {
Timber.e(e)
}
Notice, that zzg is an obfuscated var of Camera instance and it's name may be different per library releases
I am setting up the Android Device Buttons to work with my app. According to the PG/Cordova documentation I should be able to just add an listener such as
document.addEventListener("backbutton", function() {
console.log('Back Button Pressed.');
}, false);
However, when using my Nexus 7 as a test device, nothing happens.
I have also tried adding the override directly into Java:
#Override
public void onBackPressed() {
super.loadUrl("javascript:onBackKeyDown()");
return;
}
But once again, seems to do nothing. Anyone else having this issue or fixed?
Thank you.
First of all, ur function write into the console.
document.addEventListener("backbutton", function() {
console.log('Back Button Pressed.');
}, false);
You should set your device as debugging tools (, you will find below a quick hint how to do it, for more info go here )
Connect your phone to the pc
On your phone: check USB debugging;
setting => Developer Option => USB debugging
On your phone: check unknown sources;
settings >> applications >> unknown sources = true
add your device to the ADT (in your SDK)
run the project directly from the pc to the mobile :
right-click on the project => Run AS => choose your device
NOW on Back button Click, "Back Button Pressed." will be printed in the console of Eclipse.
If your device is not connected to the Computer or if your device is not set as debugging tools, Nothing will change.
In General case Use "alert()" in stead of "console.log()" if you are testing on the device without setting it as debugging tools.
Beside, dont use the native java, use the original documentation of Cordova, just add the following code into your javascript files:
function onLoad() {
document.addEventListener("deviceready", onDeviceReady, false);
}
// Cordova is loaded and it is now safe to call Cordova methods
//
function onDeviceReady() {
// Register the event listener
document.addEventListener("backbutton", onBackKeyDown, false);
}
// Handle the back button
//
function onBackKeyDown() {
// whatever you want to do
alert('Back button Pressed');
}
then you should add "onLoad()" to the body tag:
<body onLoad="onLoad()">
I need to programatically trigger text selection mode in a WebView, but the code I have used does not work on Jelly Bean?
I have been using the following code but it no longer works on Android 4.1 (Jelly Bean) because WebView.selectText, emulateShiftHeld, and the key dispatch are no longer supported on Jelly Bean.
Following code that works on all versions up to ICS is based on: How to enable the default highlight menus in android webview?
public void selectAndCopyText() {
try {
// ICS
WebView.class.getMethod("selectText").invoke(this);
} catch (Exception e1) {
try {
Method m = WebView.class.getMethod("emulateShiftHeld", (Class[])null);
m.invoke(this, (Object[])null);
} catch (Exception e2) {
// fallback
KeyEvent shiftPressEvent = new KeyEvent(0,0,
KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_SHIFT_LEFT,0,0);
shiftPressEvent.dispatch(this);
}
}
}
How do I implement similar functionality that works on Jelly Bean?
I have listed a potential solution in the comments here: How to enable the default highlight menus in android webview?
Here is the content of the potential solution:
After analyzing android.webkit.WebViewClassic I have had some success with the following:
KeyEvent enterEvent = new KeyEvent(0,0,KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_ENTER,0,0);
enterEvent.dispatch(this);
I thought more might be required as I needed to scroll down the WebView a little before the above worked when using an emulator, but after testing on a real JellyBean device the above seems to work fine.