Android manifest permissions not matching up with runtime permissions - android

bit of a strange question.
I'm trying to write some code that, for testing purposes, allows my test instance of Instrumentation to programmatically add Call Logs. It is simple but to do this, but it requires the android.permission.WRITE_CALL_LOG permission.
I've added this in my manifest
<uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
But when I use this code during runtime...
PackageManager instrumentationPM = instrumentationContext.getPackageManager();
PackageInfo info = instrumentationPM.getPackageInfo(PACKAGE_NAME,
PackageManager.GET_PERMISSIONS);
PermissionInfo[] permission_info = info.permissions;
The permission_info (aka info.permissions) array is null. Thus, during runtime no permissions are detected. Any clue what could be the issue here, and if this is at all relevant to my task of allowing my Instrumentation to add call logs?
Thanks a bunch.

This code will not return the <uses-permission> specified manifest file. Instead it will return the <permission>, which is system level permission.
I tried this code:
PackageManager instrumentationPM = getApplicationContext().getPackageManager();
PackageInfo info;
try {
info = instrumentationPM.getPackageInfo("com.example.testingproj",
PackageManager.GET_PERMISSIONS);
PermissionInfo[] permission_info = info.permissions;
if(permission_info!=null)
System.out.println(permission_info.length);
} catch (NameNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
And I have kept this permission in my manifest file:
<permission android:name="anypermission"></permission>
It gives me length = 1 in logcat.
I am not aware of getting all the <uses-permission> from manifest. But if you just want to check if there is a specific permission in manifest, you can try this:
if (instrumentationPM.checkPermission(permission.ACCESS_WIFI_STATE, getPackageName()) == PackageManager.PERMISSION_GRANTED) {
System.out.println("wifi state permission");
} else {
// do something
}

Related

How to take CLEAR_APP_CACHE permission in Android Marshmallow at runtime?

Code:
void clearCache() {
if (mClearCacheObserver == null) {
mClearCacheObserver = new CachePackageDataObserver();
}
PackageManager mPM = getPackageManager();
#SuppressWarnings("rawtypes")
final Class[] classes = {Long.TYPE, IPackageDataObserver.class};
Long localLong = Long.valueOf(CACHE_APP);
try {
Method localMethod =
mPM.getClass().getMethod("freeStorageAndNotify", classes);
localMethod.setAccessible(true);
// Start of inner try-catch block
try {
localMethod.invoke(mPM, localLong, mClearCacheObserver);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.getCause().printStackTrace();
}
// End of inner try-catch block
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
}
}
Logcat:
java.lang.SecurityException: Neither user 10206 nor current process has android.permission.CLEAR_APP_CACHE.
at android.os.Parcel.readException(Parcel.java:1620)
at android.os.Parcel.readException(Parcel.java:1573)
at android.content.pm.IPackageManager$Stub$Proxy.freeStorageAndNotify(IPackageManager.java:5081)
at android.app.ApplicationPackageManager.freeStorageAndNotify(ApplicationPackageManager.java:2500)
at android.content.pm.PackageManager.freeStorageAndNotify(PackageManager.java:4710)
at java.lang.reflect.Method.invoke(Native Method)
at com.onexsoftech.clearcacheapp.MainActivity.clearCache(MainActivity.java:278)
at com.onexsoftech.clearcacheapp.MainActivity.insertDummyContactWrapper1(MainActivity.java:495)
at com.onexsoftech.clearcacheapp.MainActivity.insertDummyContact(MainActivity.java:472)
Prior to Android 6.0, CLEAR_APP_CACHE had a protectionLevel of dangerous, so ordinary SDK apps could request it in the manifest.
As of Android 6.0, CLEAR_APP_CACHE has a protectionLevel of signature|privileged. Ordinary Android apps cannot hold this permission. You can only hold this permission if your app is signed with the firmware's signing key or you are installed on the privileged system partition.
From Android M -> CLEAR_APP_CACHE, Protection level: system|signature
Android 6.0 does not change the behavior of normal permissions (all
non-dangerous permissions including normal, system, and signature
permissions).
So it is not possible to ask for that permission in runtime. To be more precise
A signature|system permission, meaning that it can only be held by
apps that are signed with the firmware's signing key or are installed
on the system partition (e.g., by a rooted device user). From this stackoverflow Q/A.
Docs:
https://source.android.com/devices/tech/config/runtime_perms.html#affected-permissions
Add Permission in AndroidManifest.xml
<permission android:name="android.permission.CLEAR_APP_CACHE"/>
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>
Make a Constant for Request Code.
Constants.java
public static final int REQUEST_CODE_FOR_PERMISSION = 501;
Request Permission :-
public static void requestPermissionForClearCache(Activity activity) {
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.CLEAR_APP_CACHE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CLEAR_APP_CACHE)) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CLEAR_APP_CACHE}, Constatnts.REQUEST_CODE_FOR_PERMISSION);
} else {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CLEAR_APP_CACHE}, Constatnts.REQUEST_CODE_FOR_PERMISSION);
}
}
}
Override Below method in Fragment.
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if (requestCode == Constatnts.REQUEST_CODE_FOR_PERMISSION && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted successfully
} else {
// permission was NOT granted successfully
}
}

Get permission details programmatically

Is there anyway in android sdk where they provide an information for specific permission? Like how google play does, whenever you click on a permission you are able to read what does this permission do. I have this function to return me specific permissions for an application
public static List<String> getAppPermissions(Context context, String packageName) {
try {
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
return Arrays.asList(info.requestedPermissions);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return new ArrayList<>();
}
}
By this code im getting only permission names, but I'm wondering if there is any such api that return permissions and their details.
to answer my question, PermissionInfo is actually the right class to get a description about any android permission for example:
#Nullable
public static PermissionInfo getPermissionInfo(#NonNull Context context, #NonNull String permission) {
try {
return context.getPackageManager().getPermissionInfo(permission, PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
above method will return PermissionInfo instance if it could parse the permission name given to it, and then simply you could call loadDescription to load the permission description.

Blank File is saved when using screencap programatically in Android

code snippet
void takeSnapShot()
{
Process process = null;
try
{
process = Runtime.getRuntime().exec("/system/bin/screencap -p /sdcard/snapshot/test_2.png" );
try
{
process.waitFor();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I am gettin an empty file saved whereas If i use the same command through adb shell, i get my screen captured.
Any help will be appreciatable
Edit: my previous answer was mistaken, any app can use the screen capture command.
It might be a permission issue. Are you sure you have permission to write to sdcard?
Check this post, which covers your topic:
How to run android system app without root permisson?
I solved this by adding the following permission to my Manifest.
<uses-permission
android:name="android.permission.READ_FRAME_BUFFER"
tools:ignore="ProtectedPermissions"/>
NOTE: This is a protected permission, my application is a system app and also signed using the platform key.

Unknown host Exception while calling method " twitter.getOAuthRequestToken()"

I am trying to integrate twitter api using library twitter4j-core-2.1.1-SNAPSHOT.jar. But i am getting error Unknown host Exception from 2 days. here is the part of code(index by .....(1)) that is generating Exception.
public String beginAuthorization() {
//showDialog("Authorization...........");
//new AuthorizationTask(this).execute("Authorize");
try {
if (null == currentRequestToken) {
Log.e("begin","i am here the line below is throwing excetion");
currentRequestToken = twitter.getOAuthRequestToken();............(1)
}
Log.e("beginAuthorization", currentRequestToken.getAuthorizationURL());
return currentRequestToken.getAuthorizationURL();
} catch (TwitterException e) {
e.printStackTrace();
}
return null;
}
anyone have idea about this problem???
thank u in advance
Did you put permission in xml manifest?
Have you tried opening a browser in android and going to twitter.com?
Try to connect to any url from the code and see what happens.
This is what I'd forgotten to include in my AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />

jNetPcap on Android: problem with findAllDevs method!

I've sucessfully compiled jNetPcap as a shared library for Android. I have made a simple application using this code: http://jnetpcap.com/examples/classic to test the API.
The problem is that when I call the method findAllDevs and exception is raised with this message: "Can't read list of devices, error issocket: Permission denied"
I cannot understand the reason, since I have made a call in the first part of my program so as to get root permissions for my application and I test my application to a rooted phone. When I run the application, a pop up is raised with this message:"SnifferApp has been granted Superuser permissions" and then the exception occurs.
Any ideas?
Here is a piece of my code:
Process p = Runtime.getRuntime().exec("su");
/*try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} // do nothing for 1000 miliseconds (1 second)
*/
try {
System.loadLibrary(JNETPCAP_LIBRARY_NAME);
}
catch (UnsatisfiedLinkError e) {
System.out.println("Native code library failed to load.\n" + e);
}
/***************************************************************************
* First get a list of devices on this system
**************************************************************************/
int r = Pcap.findAllDevs(alldevs, errbuf);
r = Pcap.findAllDevs(alldevs, errbuf);
if (r == Pcap.NOT_OK || alldevs.isEmpty()) {
tv.append("Can't read list of devices, error is" + errbuf
.toString());
setContentView(tv);
return;
}
As far as I understand, you're creating a new process and getting superuser permission, but your app doesn't have them.
Try adding this permission in your manifest file:
<uses-permission android:name="android.permission.INTERNET" />
as I guess findAllDevs is going to open the network devices on the phone.

Categories

Resources