I have this line of code calling 2 seconds from the vibrator_service;
Vibrator v = (Vibrator)
getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(2000);
and this in my manifest
<permission
android:name="android.permission.VIBRATE" ></permission>
But I am still getting a force close java.lang.security.exception: Requires Vibrate Permission. Have I declared the permission wrong??
You need to add a uses-permission tag in the manifest file (as a child of the manifest element, same as the permission tag):
<uses-permission android:name="android.permission.VIBRATE" />
As far as I know, the permission tag is only used to add additional text/graphic information to the permissions request when downloading the app, or to add new permissions to provide additional information to your users. I usually use both to be safe.
Related
Hello Android developers, I am trying to make my app the default sms app on my phone with the following code but its not working as it is not displaying the dialog for a user to choose which app to use as the default sms app. I am aware that as of Android 10 then we need to use the RoleManager class to check if the app is the default sms app and additionally check if the app holds the role and then start an activity for the user to set the current app to have that role. I have followed every required step from the documentation and some previously posted questions on this site but there seems to be an error that is silent because no exception is thrown. Help me make this code display the dialog to the user for changing the app for the sms roles.
//register a delegate for reading the phone number
button.Click += (o, p) =>
{
Toast.MakeText(this,Telephony.Sms.GetDefaultSmsPackage(ApplicationContext),ToastLength.Long).Show();
//check first if the app is the default sms privilege holder
if (Telephony.Sms.GetDefaultSmsPackage(ApplicationContext) != PackageName)
{
//use the role manager api to change the default sms app
//check the api level
if (Build.VERSION.SdkInt > BuildVersionCodes.P)
{
Log.Debug("API", "api greater than 28");
//api level is greater than 28 then use RoleManager class
RoleManager roleManager = (RoleManager)GetSystemService(Context.RoleService);
//check if the role is available first
if (roleManager.IsRoleAvailable(RoleManager.RoleSms))
{
//log the role manager availability
Log.Debug("Sms role available", roleManager.IsRoleAvailable(RoleManager.RoleSms).ToString());
//chek if the role is held
if (roleManager.IsRoleHeld(RoleManager.RoleSms))
{
//means the app has the sms role and we do not need to change
}
else
{
Log.Debug("Info", "Sms Role is not held");
//means the app does not have the sms role and we need to request the user to change
Intent changeIntent = roleManager.CreateRequestRoleIntent(RoleManager.RoleSms);
StartActivityForResult(changeIntent,909);
}
}
else
{
//the role is not avaialble and cannot be changed
Log.Debug("Sms role available",
roleManager.IsRoleAvailable(RoleManager.RoleSms).ToString());
}
}
else
{
//api level is less than or equal to 28 use the deprecated way
Intent changeIntent = new Intent(Telephony.Sms.Intents.ActionChangeDefault);
changeIntent.PutExtra(Telephony.Sms.Intents.ExtraPackageName, PackageName);
StartActivity(changeIntent);
}
}
and here is my manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="SimCardManager.SimCardManager">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE"/>
<uses-permission android:name="android.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER"/>
<application android:allowBackup="true" android:label="#string/app_name" android:supportsRtl="true" android:theme="#style/AppTheme">
</application>
</manifest>
An answer in Android Java is also accepted as that is what I use to convert Java code to C#, the code is still Android Java working as a Xamarin Android C# binding, Thank You for your time and effort helping me.
When attempting to create a temp file on Android 10 I am getting a permission denied error. Could someone please write a tutorial on how to create one in the external storage? Most are outdated and not for current versions of Android
Here is the logcat
2020-02-22 13:46:43.766 9544-9544/com.myapp.test E/MainActivity: Image file creation failed
java.io.IOException: Permission denied
at java.io.UnixFileSystem.createFileExclusively0(Native Method)
at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:317)
at java.io.File.createTempFile(File.java:2018)
at com.myapp.test.MainActivity.create_image(MainActivity.java:915)
at com.myapp.test.MainActivity.access$200(MainActivity.java:85)
at com.myapp.test.MainActivity$6.onShowFileChooser(MainActivity.java:513)
at vo.runFileChooser(PG:10)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:336)
at android.os.Looper.loop(Looper.java:197)
at android.app.ActivityThread.main(ActivityThread.java:7762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047)
My AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:remove="android:maxSdkVersion" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
And code in the MainActivity.Java
private File create_image() throws IOException {
#SuppressLint("SimpleDateFormat")
String file_name = new SimpleDateFormat("yyyy_mm_ss").format(new Date());
String new_name = "file_"+file_name+"_";
File sd_directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return File.createTempFile(new_name, ".jpg", sd_directory); // fails due to permission denied
}
I was using official documentation to implement taking a photo from camera:
https://developer.android.com/training/camera/photobasics
yet it doesn't work and throws an exception on createTempFile method. Strangely google hasn't updated the code.
Here's a solution I've found:
Add:
android:requestLegacyExternalStorage="true"
to AndroidManifest.xml. No need to change anything in code. Works for now, but may not in upcoming Android versions.
You need to change
File sd_directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
to
File sd_directory = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
You need to add a file provider
https://developer.android.com/reference/android/support/v4/content/FileProvider
And request the read/write storage permissions at runtime.
https://developer.android.com/training/permissions/requesting
In android 10 permission isn't directly accepted. So, you have ask from user to accept permission. There's a library which you can use for asking permission. Let me add that link
It is known as Dexter Library
You have to add a line to gradle.build
implementation 'com.karumi:dexter:6.2.2'
Following source code used for single permission at a time.
Dexter.withContext(this)
.withPermission(Manifest.permission.CAMERA)
.withListener(new PermissionListener() {
#Override public void onPermissionGranted(PermissionGrantedResponse response) {/* ... */}
#Override public void onPermissionDenied(PermissionDeniedResponse response) {/* ... */}
#Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {/* ... */}
}).check();
There's way to asking for multiple permission in Dexter library. You can get that on that link
As you are using getExternalStoragePublicDirectory In android 10+, you can't write on public folder directly. One way is to use getExternalFilesDir to capture image and then use MediaStore APIs to copy file into public directory.
I need the user to check and set permission to ACCESS_BACKGROUND_LOCATION ("Allow all the time") without the option to "Allow only while using the app". My GPS Tracking app needs to continue accessing location even when the application is minimised.
I have already permissions working for ACCESS_FINE_LOCATION for Android 9.
AndroidManifest.xml--------------------------------------------------->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
TrackingActivity.java (need to include ACCESS_BACKGROUND_LOCATION)---->
private void permissionCheck1() {
int permissionCheck1 = ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck1 != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
} else {
grantedSetupGPSandMap();
}
}
I need the only permission option to be "Allow all the time" if possible. How do I set this up when checking and setting permissions?
For Android 10, if:
You omit ACCESS_BACKGROUND_LOCATION, and:
You use a foreground service with the android:foregroundServiceType="location" property set in the manifest, then:
The system will supply only the "Allow only while using the app" and "Deny" options to the user, in reference to the location permission.
I realize that's the exact opposite of what you asked for, but the point is, under this condition, "Allow only while using the app" effectively behaves like "Allow all the time", provided the aforementioned foreground service is running.
You will be able to receive location updates even when the app is offscreen. And the user does not have the option of only partially allowing location updates; they have to choose between fully allowing it, or fully denying it.
EDIT
This answer also assumes your targetSdkVersion is 29.
I am newbie to native android development. I am working on android studio. I have a tabbed activity in which i am using 2 tabs. In one tab there is a map with marker on gps location of the user. The second tab is to take picture and then to save it in the storage provided by the OS. For this i followed this tutorial, run the app on my device but it's crashes. I am running it on Marshmallow. Below is the error i get
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=android/com.android.internal.app.ResolverActivity } from ProcessRecord{e8f9820 15070:com.example.accurat.faisal/u0a228} (pid=15070, uid=10228) with revoked permission android.permission.CAMERA
at android.os.Parcel.readException(Parcel.java:1620)
at android.os.Parcel.readException(Parcel.java:1573)
at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3181)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1541)
at android.app.Activity.startActivityForResult(Activity.java:4298)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:79)
at android.support.v4.app.ActivityCompatJB.startActivityForResult(ActivityCompatJB.java:30)
at android.support.v4.app.ActivityCompat.startActivityForResult(ActivityCompat.java:146)
at android.support.v4.app.FragmentActivity.startActivityFromFragment(FragmentActivity.java:937)
at android.support.v4.app.FragmentActivity$HostCallbacks.onStartActivityFromFragment(FragmentActivity.java:1047)
at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:954)
at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:943)
at com.example.accurat.faisal.Camera$1.onClick(Camera.java:51)
at android.view.View.performClick(View.java:5716)
at android.widget.TextView.performClick(TextView.java:10926)
at android.view.View$PerformClick.run(View.java:22596)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
I searched it and found that i should ask permission for it so i followed this link and tried to add permission check like as bellow
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Check permission for CAMERA
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
// Callback onRequestPermissionsResult interceptado na Activity MainActivity
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.CAMERA},
MainActivity.REQUEST_CAMERA);
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE );
}
});
But i am getting red text of CAMERA and REQUEST_CAMERA. Though i have imported them as well but still the red text is showing
import static android.Manifest.permission.CAMERA;
import static android.Manifest.permission.RECORD_AUDIO;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Below is my manifest file
<uses-permission android:name="com.example.accurat.faisal.permission.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.hardware.camera"/>
I don't know what is the problem and don't know the solution and i am stuck to it.
Any help would be highly appreciated
You need to add permission check in your code and based on user action of accecpt or denial should show the camera preview Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running. Also, you need to ask user permission for android.Manifest.permission.WRITE_EXTERNAL_STORAGE if you are creating a file which will be used as an input for image(captured via camera).
After doing tons of research on the topic, I learned that my app may not show up for tablets in the Play Store if I have some permissions that the tablet cannot handle. Here are my current permissions:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.VIBRATE" android:permission ="false" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.INTERNET" />
Will any of these permissions cause the app to not show up in the play store?
Some tablets may not be able to handle the <uses-permission android:name="android.permission.READ_PHONE_STATE" /> because don't get calls...So, I need to do something in my java code saying:
if(Device has the ability to get calls){ //Execute code}
So, since the telephone thing is optional, I changed it's permission to:
<uses-feature android:name="android.permission.READ_PHONE_STATE" android:required="false"/>
How do I get that? If you need it, this is where I am actually checking if the user is getting a call, I use it to mute my application:
private PhoneStateListener phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (state == TelephonyManager.CALL_STATE_RINGING) {
onPhoneCallInterrupt(); //Method I created that just mutes the audio
} else if (state == TelephonyManager.CALL_STATE_IDLE) {
} else if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
onPhoneCallInterrupt(); //Method I created that just mutes the audio
}
}
};
So, what do I do to handle the exception that may occur if a tablet is using the app, like this?
if(Device has the ability to get calls){ //Execute code}
Thanks,
Ruchir
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE); //gets the current TelephonyManager
if (tm.getSimState() != TelephonyManager.SIM_STATE_ABSENT){
//the device has a sim card
} else {
//no sim card available
}
Check more here
Keep your phone state permission on an if-else block. When user will try to access that feature or you might need to check phone state, throw a dialog box on the screen. This link shows how to ask for user's permission.
From API 23, User's will need to explicitly permit each and every permission so, it is a good thing if you do that for all.
Beside, upon users permission, the manifest file will be overwritten so, you won't have to worry about that either.
Does it solve ur issue?