I am building an Android Application that needs the Notification Accessibility permission.
My thought is to take the user to the Notification Accessibility page when the app is first started, How can I do this via intent?
To open NotificationAccessSettingsActivity via intent you could do something like this:
startActivity(new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));
If you want to check the permission you could use:
private boolean isNotificationServiceRunning() {
ContentResolver contentResolver = getContentResolver();
String enabledNotificationListeners =
Settings.Secure.getString(contentResolver, "enabled_notification_listeners");
String packageName = getPackageName();
return enabledNotificationListeners != null && enabledNotificationListeners.contains(packageName);
}
Related
I am trying to upload an image selected from gallery to my Springboot server, but when my service try to post the image I get permission denied for the file path. I have added these permissions to my AndroidManifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- permission below just in case, should not be needed I believe -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I then ask for permission in real time to select the image, and then I want to place it in an inflated view where the user can provide more details about the image, then add it to a report which I will later post.
Since I got this permission trouble I also asked for permission again when I try to submit this Report object containing the images (Uri).
But still I get this error:
Caused by: java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/IMG_20200206_120434.jpg (Permission denied)
Every hit I find on this error on google will point to someone who don't ask for this real-time permission, but I even do it once to much I believe.
This is some related snippets of my code:
else if (view.getId() == R.id.stubNewBreedingReportSelectImageButt) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
} else {
getPhotoFromPhone(); // this starts the intent to pick an image
}
}
}
else if (view.getId() == R.id.stubNewBreedingReportSubmitButt) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 2);
} else {
submitNewBreedingReport();
}
}
}
This is from my onClick(View view) method. The first one works since I am allowed to pick an image from the gallery. The second one should probably not need to check the permissions based on every example I have found of projects uploading images from android.
In my onActivityResult(int requestCode, int resultCode, Intent data) method I inflate this "add image details view". I also store the selected Uri as a private Uri selectedImg in the activity for future use. This all seems to work pretty much fine.
Then when I submit the image (in the submitNewReport() method) I use an ExecutorService (java class) to start a new async thread for the upload. In this Callable<> I get an instance of Springs RestTemplate and try to post the image, but when my restTemplate try to call and fetch the file from my Uri I get the permission denied.
This is the upload method in my apps ImageService:
public Gallery uploadPictureWithInfo(Uri uri, Map<String,Object> imgParams, Context context) {
if (uri.getPath() != null) {
File resourceFile = new File(getPathFromUri(uri,context));
//if (resourceFile.exists()) {
Gallery saved = null;
Map<String,Object> params = new HashMap<>();
params.put(PARAM_FILE, new FileSystemResource(resourceFile));
if (imgParams.get(PARAM_GALLERY_ID) != null || (long) imgParams.get(PARAM_GALLERY_ID) > (long) 0) {
params.put(PARAM_GALLERY_ID, imgParams.get(PARAM_GALLERY_ID));
if (imgParams.get(PARAM_DESCRIPTION) != null) {
params.put(PARAM_DESCRIPTION, imgParams.get(PARAM_DESCRIPTION));
}
if (imgParams.get(PARAM_PHOTOGRAPH) != null) {
params.put(PARAM_PHOTOGRAPH, imgParams.get(PARAM_PHOTOGRAPH));
}
if (imgParams.get(PARAM_USER_ID) != null && (long) imgParams.get(PARAM_USER_ID) > 0) {
params.put(PARAM_USER_ID, imgParams.get(PARAM_USER_ID));
}
HttpEntity requestEntity = new HttpEntity<>(params, AquaDbConfig.getImageHeaders());
ResponseEntity<Gallery> responseEntity =
restTemplate.exchange(AquaDbConfig.getApiUrl() + "/images/uploadImgWithInfo", HttpMethod.POST, requestEntity, Gallery.class);
if (responseEntity.hasBody()) {
saved = responseEntity.getBody();
}
return saved;
}
//}
}
return null;
}
public static String getPathFromUri(Uri uri, Context context) {
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor c = context.getContentResolver().query(uri,filePath, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
return picturePath;
}
I commented out the check for the file.isExist() to get past that test since it wont generate a stack trace otherwise.
So my question is HOW do I get to read the image file when I POST it to the server? I read a little about FileProvider class, but it seems to me that it is used to send files through Intents to new Activites or other Apps. It don't seem to me like it is intended for this because I never leave my Activity exept for picking the image in the gallery. The diffrent steps of creating this ReportedBreeding object is handeled by inflated ViewStubs and not new activites. Also the Uri I use don't refer to any directories I created for my app but rather the users image gallery (external storage).
I also tried to declare my ImageService as a Service in the android manifest, even though I'm not sure we talk about the same kind of service. I then added it this permission but it made no diffrence:
<service
android:name=".service.MyImageFactory"
android:permission="android.permission.READ_EXTERNAL_STORAGE">
</service>
If you know how to get the permission all the way to this RestTemplate POST method (which noone else seems to need in my reviewed examples) or how I can get around this problem, please share! I'm starting to get a little frustrated and stuck. The problem to me is Why do android require yet another permission check and how do I provide it or work around it in my uploadPictureWithInfo(..) method?
Try asking the permission for WRITE_EXTERNAL_STORAGE before getPhotoFromPhone()
For Android 10 this may be the permission issue, there are two solutions for that to handle for now. First method is to permission to manifest Application tag: android:requestLegacyExternalStorage="true"
The other one is to use openFileDescriptor
val parcelFileDescriptor = context.contentResolver.openFileDescriptor(fileUri, "r", null)
val inputStream = FileInputStream(parcelFileDescriptor.fileDescriptor)
fun ContentResolver.getFileName(fileUri: Uri): String {
var name = ""
val returnCursor = this.query(fileUri, null, null, null, null)
if (returnCursor != null) {
val nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
returnCursor.moveToFirst()
name = returnCursor.getString(nameIndex)
returnCursor.close()
}
return name
}
val file = File(context.cacheDir, getFileName(context.contentResolver, fileUri))
val parcelFileDescriptor = context.contentResolver.openFileDescriptor(fileUri, "r", null)
parcelFileDescriptor?.let {
val inputStream = FileInputStream(parcelFileDescriptor.fileDescriptor)
val file = File(context.cacheDir, context.contentResolver.getFileName(fileUri))
val outputStream = FileOutputStream(file)
IOUtils.copy(inputStream, outputStream)
}
***Facebook deprecated xmpp api.
Is there a way to open an intent (or pass data to fb) to send chat message on android device?
Facebook & Messenger apps installed on the device.
Thanks :-)
You need to pass uri to the intent
Here 100005727832736 is the user id of the person who you want to
message to
Uri uri = Uri.parse("fb-messenger://user/100005727832736");
Here is my sample code
Uri uri = Uri.parse("fb-messenger://user/100005727832736");
Intent toMessenger= new Intent(Intent.ACTION_VIEW, uri);
try {
startActivity(toMessenger);
}
catch (android.content.ActivityNotFoundException ex)
{
Toast.makeText(context, "Please Install Facebook Messenger", Toast.LENGTH_LONG).show();
}
}
This is what worked for me and i haven not tested this for some time now.
To launch facebook app let urlString = "fb://page/your_fb_page_id"
To launch facebook messenger let urlString = "fb-messenger://user/your_fb_page_id"
FB page id is usually numeric. To get it, goto Find My FB ID input your profile url, something like www.facebook.com/edgedevstudio then click "Find Numberic ID".
Voila, you now have your fb numeric id. replace "your_fb_page_id" with the generated Numeric ID
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(urlString))
if (intent.resolveActivity(packageManager) != null) //check if app is available to handle the implicit intent
startActivity(intent)
I am making one app to allow user to share all video from any sharing app. My issue is file attached successfully but the file content is not attaching. below is my full source code. Let me know where I am making a mistake.
private void shareVideo() {
Intent localIntent = new Intent("android.intent.action.SEND");
Uri localUri = Uri.fromFile(new File(CorporateAdaptor.this.rawVideoId + ".mp4"));
String str = MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(localUri.toString()));
localIntent.setType(str);
localIntent.setAction("android.intent.action.SEND");
if (str == null) {
str = "*/*";
}
localIntent.setType(str);
localIntent.putExtra("android.intent.extra.STREAM", localUri);
CorporateAdaptor.this.mContext.startActivity(Intent.createChooser(local Intent, "Where you want to share?"));
}
This is my code that was I am using when user click on the share button. It will open a share dialog and when I select the gmail app, the file is attached but it's showing me a toast message "Couldn't find attachment". And when I click on send email file was not sending.
I want to open the Deezer Android Application from URI using Android Intent.
My code is:
try {
uri = "deezer://track/"+track_id;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
activity.startActivity(intent);
} catch (Exception e) {
uri = "http://www.deezer.com/track/"+track_id;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
activity.startActivity(intent);
}
However, the URI "deezer://track/track_id is never detected by Deezer and doesn't work.
Anybody knows the correct URI syntax for that ?
(I use the same code for Spotify and it works with the URI: spotify:track:track_id)
If you really want to use the deezer:// scheme, you can use the following uri :
uri = "deezer://www.deezer.com/track/"+track_id;
Edit :
You can also use some query parameters to add behavior to your link, for instance the following uri : deezer://www.deezer.com/album/10596327?autoplay=true&start_index=13 will open the deezer app on the album's page immediately and will start playing with the 14th track (0 based index).
I downloaded apk file from url(my server) and save it in sdcard. If user install it from sdcard, I want to know, whether is any notification that app is installed successfully or is app istalled in device. Is there any callback on installed app
try this code :
protected boolean isAppInstalled(String packageName) {
Intent mIntent = getPackageManager().getLaunchIntentForPackage(packageName);
if (mIntent != null) {
return true;
}
else {
return false;
}
}
to get the package name of the app easily : just search your app in the google play website , and then you will take the id parameter ( it is the package name of the app) . Example :
you will search on Youtube app on google play , and you will find it in this url :
https://play.google.com/store/apps/details?id=com.google.android.youtube&feature=search_result#?t=W251bGwsMSwxLDEsImNvbS5nb29nbGUuYW5kcm9pZC55b3V0dWJlIl0.
the package name is the id param, so it is : com.google.android.youtube
And then when you want to test , you will just have :
String packageName = "com.google.android.youtube";
boolean isYoutubeInstalled = isAppInstalled(packageName);
PLUS : if you want to get the list of all installed apps in you device , you can find your answer in this tutorial
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List pkgAppsList = context.getPackageManager().queryIntentActivities( mainIntent, 0);
You'll get the list of all installed applications on Android.
Use this to check if an application is installed
PackageManager pm = context.getPackageManager();
List<ApplicationInfo> list = pm.getInstalledApplications(0);
for (int i = 0; i < list.size(); i++) {
if(list.get(i).packageName.equals("com.my package")){
//do what you want
}
}
In Youtube Player API, you can access YoutubeIntents class and use isYoutubeInstalled to verify if device has the Android app or not.