Permission denial: Can't access the SurfaceFlinger - android

I get this error when running my app. I also included the permission for surfaceFlinger in manifest.xml
"uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
but still it give the same error " can't access the SurfaceFlinger" in LogCat.
Basically i want to run the Development setting code in Dev tools.
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
try {
Class partypes[] = new Class[1];
partypes[0] = String.class;
Method getService= ServiceManager.getMethod("getService", partypes );
Object arglist[] = new Object[1];
arglist[0] = "SurfaceFlinger";
IBinder flinger= (IBinder)getService.invoke(smObject, arglist );
// IBinder flinger = ServiceManager.getService("SurfaceFlinger");
if (flinger != null) {
Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
data.writeInt(isChecked ? 1 : 0);
flinger.transact(mCode, data, null, 0);
data.recycle();
updateFlingerOptions();
}
} catch (RemoteException ex) {
}
**catch (SecurityException e) {
// TODO Auto-generated catch block
String err=e.toString();
Toast.makeText(DevelopmentSetting.this, err, Toast.LENGTH_SHORT).show();
}**
catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} 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.printStackTrace();
}
}
}
In catch SecurityException it gives the error java.lang.securityException but logcat it says permission denied : can't access surfaceFlinger.
and the manifest.xml is here
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nustian.android"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER"/>
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".DevelopmentSetting"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Somebody help me.

Your app needs to be signed with the platform certificate to access this permission. Only system apps generally have this. More info here:
https://groups.google.com/forum/#!topic/android-porting/aN6D_vL9xxE

As a workaround, add this to your manifest file. UID media is able to use the surface flinger APIs, so sharing UID with it will allow your app to use it as well.
coreApp="true"
android:sharedUserId="android.uid.media"

Don't forget to add its relative permission:
<uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />

Related

Is it possible to make an L2CAP socket connection by using Bluetooth?

I have a collection of bluetooth earpieces and wanted to be able to connect directly to their AVRCP profile.
The main sticking point is that there is no publicly accessible way to construction an L2CAP socket.
In theory the code below ought to work, but I am getting a permssion denied error.
I do have these in my manifest:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
The code snippet is here:
private BluetoothSocket createL2CAP(BluetoothDevice bd, UUID uuid) {
BluetoothSocket result = null;
try {
c=BluetoothSocket.class.getDeclaredConstructor(int.class,int.class,boolean.class,boolean.class, BluetoothDevice.class,int.class,ParcelUuid.class);
result=(BluetoothSocket) c.newInstance(BluetoothSocket.TYPE_L2CAP, -1, true, true, bd, -1, new ParcelUuid(uuid));
} catch (NoSuchMethodException e) {
addln("BluetoothSocket: No Such Constructor");
} catch (IllegalAccessException e) {
addln("BluetoothSocket: Illegal access");
} catch (InvocationTargetException e) {
addln("BluetoothSocket: Target exception "+e.getMessage());
} catch (InstantiationException e) {
addln("BluetoothSocket: "+e.getMessage());
}
return result;
}
It's finding the constructor, but throwing the IllegalAccessException.
Has anyone had any luck persuading Android Bluetooth to make any connection type other than RFCOMM? And/or is there a different approach which may have more success?
(PS: addln is just sending messages to a textview so I can see what is happening)

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
}
}

Uploading TXT to dropbox

I started exploring Android app developing and I'm trying to upload a plain txt file to dropbox to start off. Whenever I've got this working I'll go up a level to pdf etc.
Anyways I keep running stuck in uploading to dropbox.
I've included the libraries, got the activity in my AndroidManifest and tried to follow the official guide as good as I can.
Without further nonsense, this is my code:
AndroidManifest.xml:
<activity
android:name="com.dropbox.client2.android.AuthActivity"
android:launchMode="singleTask"
android:configChanges="orientation|keyboard">
<intent-filter>
<!-- Change this to be db- followed by your app key -->
<data android:scheme="db-mykeyhere" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Layout file where I trigger the onclick to upload on:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:context=".HelloDropboxActivity" >
<Button
android:id="#+id/dropbox_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center"
android:text="#string/link_button"/>
<TextView
android:id="#+id/test_output"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
My activity:
public class Settings extends Activity{
final static private String APP_KEY = "myAppKeyIsHere";
final static private String APP_SECRET = "myAppSecretIsHere";
final static private AccessType ACCESS_TYPE = AccessType.APP_FOLDER;
// In the class declaration section:
private DropboxAPI<AndroidAuthSession> mDBApi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
// And later in some initialization function:
AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session = new AndroidAuthSession(appKeys, ACCESS_TYPE);
mDBApi = new DropboxAPI<AndroidAuthSession>(session);
}
public void dropbox_button(View v){
mDBApi.getSession().startAuthentication(Settings.this);
String filePath = getApplicationContext()
.getFilesDir()
.getPath()
.toString() + "/magnus-opus.txt";
File file = new File(filePath);
try {
file.createNewFile();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
Entry response = mDBApi.putFile("/magnum-opus.txt", inputStream,
file.length(), null, null);
Log.i("DbExampleLog",
"The uploaded file's rev is: " + response.rev);
} catch (DropboxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void onResume() {
super.onResume();
if (mDBApi.getSession().authenticationSuccessful()) {
try {
// Required to complete auth,
// sets the access token on the session
mDBApi.getSession().finishAuthentication();
AccessTokenPair tokens = mDBApi
.getSession()
.getAccessTokenPair();
} catch (IllegalStateException e) {
Log.i("DbAuthLog", "Error authenticating", e);
}
}
}
And finally my error log:
Could anybody tell me whats wrong here or help me ahead?
For now I just want to be able to upload a .txt file to my dropbox with ANYTHING in it.
Thanks
~Yenthe
You're getting a NoClassDefFound so it sounds like the library isn't properly included. How did you add the library?

Checking server availability doesn't work

I'm trying to check if server is available but when running this code I get error that server is not available or sometimes application freezes even server is properly running:
InetAddress in;
in = null;
try {
in = InetAddress.getByAddress(new byte[] { (byte)192, (byte)168, (byte)16, (byte)48});
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (in.isReachable(5000)) {
loadProduct();
} else
{
showAlertBox("Warning", "Server not available!");
}
} catch (IOException e) {
showAlertBox("Warning", "Server not available!");
}
Is there any better way to check if server is online?
Is there any better way to check if server is online
Yes. Try to connect to it. That is an infallible test. Don't do it until you need to, of course. Don't try to predict the future. Just connect and handle the failure.
I have tried with this
Socket socket = null;
boolean reachable = false;
try {
socket = new Socket("192.168.16.48", 80);
reachable = true;
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
showAlertBox("Warning", "Server not available!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
showAlertBox("Warning", "Server not available!");
} finally {
if (socket != null) try { socket.close(); } catch(IOException e) { }
}
It works, but sometimes I get meesage that that applications is not responding, even if socket timeout is adjusted.
You can try to locate the server using its host name. The advantage: unlike the dynamic ip address, the host name probably has a longer validity. In the following example, both network interfaces can refer to the same host.
byte[] b = { 10, 0, 0, 1 };
String name = "Hostname";
InetAddress ia = Inet4Address.getByAddress(b);
InetAddress ia2 = Inet4Address.getByName(name);
Another possible solution: before using network operations on android, you must get the corresponding permissions from the android manifest. I don't know exactly, which of the following are must-haves:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

Send http-get from PreferenceFragment (live-wallpaper)

I created a wallpaper (for my Android 4.0.3) but I have a problem with the preferences.
When I try to invoke a service http-get from PreferenceFragment, I do not get any response. In practice, it seems that call is lost. I tried with a call like:
InputStream stream = null;
StringBuilder fos = null;
try {
URL url = new URL("http://.....");
stream = url.openConnection().getInputStream();
InputStreamReader reader = new InputStreamReader(stream);
fos = new StringBuilder();
int next = -1;
while ((next = reader.read()) != -1) {
fos.append((char)next);
}
} catch (Exception e) {
// ...
} finally {
// ...
}
or with an external framework like libgdx:
HttpRequest httpRequest = new HttpRequest(HttpMethods.GET);
httpRequest.setUrl("http://.....");
NetJavaImpl net = new NetJavaImpl();
net.sendHttpRequest(httpRequest, this);
but nothing happened. On the device no trace about this or a probability exception is present.
I have a manifest like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.mytest.live"
android:installLocation="preferExternal"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-feature
android:name="android.software.live_wallpaper"
android:required="true" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".MyWallpaperSettings"
android:exported="true"
android:hardwareAccelerated="false"
android:label="MyWallpaperSettings"
android:permission="android.permission.INTERNET" />
<service
android:name=".MyWallpaper"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:permission="android.permission.BIND_WALLPAPER" >
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/livewallpaper"
android:value="true" />
</service>
</application>
</manifest>
Do you have any idea? I'm going crazy :(
*edit: Solved, Thanks!! *
private class SendAsyncTask extends AsyncTask<String, String, String>
{
protected String doInBackground(String... status)
{
String result = "";
try
{
String url = "my magic http-get";
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(new HttpGet(url));
if(response != null && response.getEntity() != null)
{
InputStream stream = response.getEntity().getContent();
try
{
// parse an XML with libgdx ...
XmlReader xmlReader = new XmlReader();
Element root = xmlReader.parse(stream);
Array<Element> childs = root.getChildrenByNameRecursively("mykids");
for (Element child: childs)
{
Element myelement = child.getChildByName("name");
//do something...
}
}
catch (Exception e)
{
//
}
finally
{
try
{
stream.close();
}
catch (Exception e)
{
//
}
}
}
}
catch (Exception e)
{
//
}
return result;
}
protected void onPostExecute(String result)
{
super.onPostExecute(result);
}
}
You could possibly get a NetworkOnMainThreadException because you made a network connection in a PreferenceFragment, which runs on main UI thread.
If so, you could move network jobs to a background service. Note that Service runs on main UI thread too. So you need Thread inside the service.
A side note: it seems you swallowed all exceptions with:
try {
// ...
} catch (Exception e) {
// ... => HERE
}

Categories

Resources