Runtime request permission in NativeScript Android app - nativescript

I code an application in Native Script and I need to use requestPermission after first launch app. I know how to use request permission, but I don't know how to make it work after first running the application. Where I must use request-permission function in app ? In ngOnInit () ?

You may use nativescript-permissions plugin to acquire runtime permissions on Android.
Use hasPermission(permissionName); method to know whether your app already has the permission Or you are yet to acquire it.
Generally it's recommended to ask for permission only when it's absolute necessary. For example, if you want to access micro phone to record anything you would request for permission only when user tries to record one, not upon launch.
You could still ask permissions upon launch, that would work. But in my opinion that could be annoying to the user. May be he is not intended to use that particular feature of the app but just the rest.

// HTML
<Button text="Take Permissions" (tap)="getPermission()"></Button>
// TS File
import * as camera from "nativescript-camera";
getPermission() {
camera.requestPermissions().then(
function success() {
console.log('granted');
},
function failure() {
console.log('failure');
}
);
}
// Search AndroidManifest.xml and add this code in all the occurrences.
<uses-permission android:name="android.permission.CAMERA" />
That's all!

Related

Which event type is triggered when a slack app is installed onto a workspace for the first time?

I'm trying to build an app that does something when it is first installed onto a workspace, eg: Ping every team member.
I couldn't find an event type that gets triggered upon app install:
https://api.slack.com/events
Is there a way to make this happen?
I think there might be a misunderstanding of the events concepts here. Events are always directly linked to one specific Slack app and needs to be processed by that very app. There is no such thing as "general" events for things happening on a workplace, like a new app being installed. Ergo there is no event for app installation.
Nevertheless you can implement the functionality you mentioned with Slack, e.g. pinging all team members once an app is first installed. All you need to do is include this function in the installation process of your Slack app and e.g. start pinging after the installation process is complete and the app verified that it was the first installation to this workspace. You do not need an event for that.
This is a partial answer because I was wondering the same thing and wanted to share what I found. On this oauth tutorial, it has the following code snippet:
app.get('/auth', function(req, res){
if (!req.query.code) { // access denied
return;
}
var data = {form: {
client_id: process.env.SLACK_CLIENT_ID,
client_secret: process.env.SLACK_CLIENT_SECRET,
code: req.query.code
}};
request.post('https://slack.com/api/oauth.access', data, function (error, response, body) {
if (!error && response.statusCode == 200) {
// Get an auth token
let oauthToken = JSON.parse(body).access_token;
// OAuth done- redirect the user to wherever
res.redirect(__dirname + "/public/success.html");
}
})
});
I believe instead of the line res.redirect(__dirname + "/public/success.html"); at that point you can make a request to ping everyone or even call a function to do so directly there, and it will trigger immediately once the app has been installed.

Xamarin-System.UnauthorizedAccessException: Access to the path is denied

I'm trying to download a file and I'm getting System.UnauthorizedAccessException: Access to the path "/storage/emulated/0/Download/test.pdf" is denied. I have set required permission in Android Manifest file.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Download Path:
Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads)
If i use the below path as my download path i can able to download the file. But i cant able to share the PDF file to google drive, drop box or any other System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
I am using Xamarin.Forms v2.4.0.282 and Xamarin.Android.Support packages v25.4.0.2.
Note: The code was woking fine when use Xamarin.Forms version 2.3.5.256-pre2 and Xamarin.Android.Support packages v23.3.0
Please suggest your ideas to resolve the issue.
Thanks in Advance.
Depending on the version of Android you are using even with the permissions added in the manifest in 6.0 or up the user has to explicitly enable the permission when the app runs and on lower versions permission is asked during install. For example, on startup of the app I created a method to check if it is enabled and request permission if it's not.
private void CheckAppPermissions()
{
if ((int)Build.VERSION.SdkInt < 23)
{
return;
}
else
{
if (PackageManager.CheckPermission(Manifest.Permission.ReadExternalStorage, PackageName) != Permission.Granted
&& PackageManager.CheckPermission(Manifest.Permission.WriteExternalStorage, PackageName) != Permission.Granted)
{
var permissions = new string[] { Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage };
RequestPermissions(permissions, 1);
}
}
}
You can also use the support library to do this, which is simpler and allows you to not have to check the Android version. For more info check out google's documentation.
If targeting API 29+, you will get the error even if you request the permission and user grants it, because they changed how storage works.
The correct solution is to look how it should be done on API 29+ and do it.
But if you are like me, tired of Android making things more complicated every day, just add android:requestLegacyExternalStorage="true" to your manifest <application> tag and you are saved until you start targeting API 30.
Those of you who are facing this issue after your app is Targeting API29 or higher, please go to this link and check LandLu's Answer:
https://forums.xamarin.com/discussion/171039/saving-files-to-external-storage
Earlier I was accessing Folder path using
return Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
But using this line solved my problem:
return Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath;
You need user's permission on run time even you have mentioned them in your manifest file if you are running Android api level 23 or greater. Check and if user has not yet granted granted READ_EXTERNAL_STORAGE & WRITE_EXTERNAL_STORAGE, use the bellow code;
var permissions = new string[] { Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage };
RequestPermissions(permissions, 77);
If i use the below path as my download path i can able to download the
file. But i cant able to share the PDF file to google drive, drop box
or any other
System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
You are storing files on app's private storage. All files saved to the internal storage are private to your application and other applications ( google drive, drop box or any other ) cannot access them (nor can the user). You can use any public folder for that purpose;
var finalPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads);
replace
Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
with
Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath;

Android 6 runtime permission for accessing gallery

I got questions about Android 6 (Marshmallow) runtime permission. If user wants to pick a photo from gallery, should we ask for READ_EXTERNAL_STORAGE permission?
Seems like I could access the gallery even though I turn off the Storage permission.
You need to ask for READ_EXTERNAL_STORAGE. You will be able to access the gallery without it, but if you want to do anything with the media you get from the gallery you will need the READ permission.
A quick test on what happens in onActivityResult after an image has been picked form the gallery:
Permission Denial: reading com.android.providers.media.MediaProvider
uri content://media/external/images/media from pid=8405, uid=10177
requires android.permission.READ_EXTERNAL_STORAGE, or
grantUriPermission()
For custom permission,you may use runtime permission if you are using Android 6.0 or above.This code may help you .
If your app doesn't already have the permission it needs, the app must
call one of the requestPermissions() methods to request the
appropriate permissions. Your app passes the permissions it wants, and
also an integer request code that you specify to identify this
permission request. This method functions asynchronously: it returns
right away, and after the user responds to the dialog box, the system
calls the app's callback method with the results, passing the same
request code that the app passed to requestPermissions().
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
To Know more about runtime permission
https://developer.android.com/training/permissions/requesting.html

Meteor shortcut to get the profile picture for the currently logged in user, regardless of platform

There are questions about getting the profile image from Twitter, Facebook or Google, but it would be nice if there were a simple and extensible wrapper that returned the profile image regardless of the current user's account service.
I think you would want to set the users profile picture yourself. Because the services do not have a standard way to store profile picture. And the meteor oauth has no required code for each service class to implement.
You could set it on account creation. This would require writing code for each service.
Accounts.onCreateUser(function (options, user) {
if (user.services.google !== undefined) {
user.profile.profile_picture = user.services.google.picture;
}
if (user.services.twitter !== undefined) {
user.twitter.profile_picture = user.services.twitter.profile_url; // sudo param name
}
return user;
})
or on publish.
In the meantime there is an Atmosphere package that returns the user profile picture and works for a lot of auth services:
bengott:avatar
Instead of bengott:avatar (which is now deprecated), use the utilities:avatar package instead
You might also want to look at the accounts-meld package.

FB.ui permissions.request issue in new OAuth window

I having an issue with FB.ui permissions.request window.
FB.ui({
method: 'permissions.request',
perms: 'publish_actions',
display: 'popup'
},function(response) {
// This function is never called ? });
Context :
I use the new OAuth window (with timeline), i have configured my apps to work with it.
I'm french and use Facebook in French.
First issue :
- My callback function is never called ...
Second issue :
- The new OAuth window, seem to be not the good window.
It's called 'permission request' but inside it is the copy of login window. And no permission request is displayed.
So, my question is : how can i do the permission request in js ?
How displaying this window : https://developers.facebook.com/attachment/app_extended_perms.png/ ?
Thanks.
The reason you are not seeing it is because the application process has become a two step process.
Being that the person accepts to login into your application.
Being the person accept your extended permission which is where the callback url comes into play.
Documentation can be found here.
So the reason your callback isn't being called is because the two step process. I would suggest making the response attached to second page that is called.
I am not sure how the JS SDK works but it is how I managed to do it.
Goodluck.
Disable "Enhanced Auth Dialog" in your app's advance settings and see if it works. If you want to stick with Enhanced Auth Dialog then checkout Setup Auth Dialog Preview for Authenticating user section of this tutorial.

Resources