[Q] Android permissions inside the framework - Android Software Development

Hi,
I added a system service into the framework (hence running in the system_process). Via Binder.getCallingUid() I can determine the calling process/app. So far so good.
But if my service tries to use other system services (e.g. the LocationManager) a SecurityException is thrown because LocationManager thinks it is called by the original app that called my service.
From what I understood, system services have all permissions by default, so this should not be the case, should it?
From programming4.us/Mobile/1304.aspx:
Binder services are free to make other binder calls, but these calls always occur with the service’s own identity (UID and PID) and not the identity of the caller.
Click to expand...
Click to collapse
Here some code to illustrate the problem:
Code:
public class MyService implements IInterface {
public IBinder asBinder() {
return mBinder;
}
private final IMyService.Stub mBinder = new IMyService.Stub() {
public Bundle doSomething() {
int uid = Binder.getCallingUid(); // uid of the calling app
int myUid = Process.myUid(); // my uid == 1000
...
try {
ILocationManager lm = ILocationManager.Stub.asInterface(ServiceManager.getService("location"));
Location myLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
} catch (Exception e) {
SecurityException is thrown. Requires ACCESS_FINE_LOCATION
}
}
};
}
Thanks in advance for any help or comments!

Just in case anyone faces the same problem:
Calling Binder.clearCallingIdentity() solves the problem.

Related

Application Request for Weight Watchers Points Calculator

Can someone make a .cab or an .exe program to calculate Weight Watchers points? I found this article on the internet where it looks like someone as already done it but they did not post it. Here is the article
http://geekswithblogs.net/cdahlinge...-mobile-meets-weight-watchers--mvp-style.aspx
Craig Dahlinger
<< Presenting at Richdmond code camp 2008.2 | Home | mshtml – the ongoing adventure >> windows mobile meets weight watchers : MVP style Ok, so I know it has been a long time since a post, but it has been really busy with work and family. I have been busy coding and learning lots of new stuff. I work with a great bunch of developers and my current team lead is a great mentor.
Well for the new year the wife and I decided to get back into shape. I started hitting the gym and so did she but she is also doing weight watchers with a friend. One of the things they do is they have to calculate points on a daily basis. These points are comprised of calories, fat and fiber. There is a formula for these three which in turn results in the number of points a particular item is. A few months ago I convinced the wife to get a windows mobile device (woo hoo!) and she is a good power user. So one night she asks me, “Is there a way I can just enter in the calories, fat and fiber on my phone and it tell me how many points something is?”. I did some searching and there are numerous online versions of the calculator but no native ones for windows mobile. I found the formula here, and started to get to work.
I wanted to approach this application using the MVP design pattern. I know it may be overkill for this simple of an application but I thought it would be good practice.
I started with the interface for the data model, in this case it would be the main caloric properties of food.
namespace WWPC.Common.Interfaces{ public interface IFoodModel { int Fiber { get; set; } int Calories { get; set; } float Fat { get; set; } int Points { get; set; } int CalculatePoints(); }}I then wrote up the interface for the view for the model.
namespace WWPC.Common.Interfaces{ public interface IFoodCalcView { int Calories { get; } int Fiber { get; } float Fat { get; } int Points { set; } event EventHandler DataChanged; }}Next, came the interface for the presenter.
public interface IFoodCalcPresenter { void OnCalculatePoints(); }
Ok, now that I got my main interfaces in place, time to code up the implementation. I started with the model first since this was the class that would provide the implementation for calculating the caloric points. Using the formula mentioned above, the CalculatePoints() method came out like so:
public int CalculatePoints(){ var calories = Convert.ToDecimal(Calories); var cal = calories / 50; var totalFat = Convert.ToDecimal(Fat); var fat = totalFat / 12; var fiber = Convert.ToDecimal(Fiber); return Points = Convert.ToInt32(Math.Round(cal + fat - (fiber/5), 0)); } With the model complete, I then moved to the presenter. The presenter would be responsible for binding the model to the view responding to the data changes in the view and rebinding those changes to the model. I made the presenter with an overloaded constructor to take a view and a model. The presenter then binds to the data changed event on the view which enables the presenter to update the model from the view. The OnCalculatePoints() method will update the view with the points value after using the model for calculation.
namespace WWPC.Common{ public class FoodPresenter : IFoodCalcPresenter { private readonly IFoodCalcView _View; private readonly IFoodModel _Model; public FoodPresenter(IFoodCalcView view, IFoodModel model) { _View = view; _View.DataChanged += new EventHandler(_View_DataChanged); _Model = model; } void _View_DataChanged(object sender, EventArgs e) { SetModelFromView(); } private void SetModelFromView() { _Model.Calories = _View.Calories; _Model.Fat = _View.Fat; _Model.Fiber = _View.Fiber; } #region IFoodCalcPresenter Members public void OnCalculatePoints() { _View.Points = _Model.CalculatePoints(); } #endregion }}
With the presenter done it was time to implement the view. I wanted a simple mobile form where you can enter in data quickly and then calculate the results. I initially tried using a label to display the result, but did not like it. I then tried a mobile gauge control, but that took up too much space on the small screen. Finally I decided to use the notification class for windows mobile. I did not use the managed wrapper version, I used the the version created by Christopher Fairbairn, found here. This version has an awesome implementation which exposes many features of the notification class. I wanted to give the user the ability to dismiss the notification when they were done reading the results. Also using the notification class the UI was able show the needed text boxes for entry and the SIP panel along with the results without needing to scroll the screen. Here is a screen shot of the main form.
Now with the controls in place on the form, I can implement the view. The form creates a new presenter and passed into it a new model during construction. When the calculate menu option is clicked the main form raises the data changed event then calls the OnCalculateMethod on the presenter. When the presenter binds the model to the view, during the set of the points value, the notification is shown to the user via the ShowNotification method.
namespace WWPC.Calc{ public partial class WWPCalculator : Form, IFoodCalcView { private readonly FoodPresenter _Presenter; private NotificationWithSoftKeys _Notification; public WWPCalculator() { InitializeComponent(); _Presenter = new FoodPresenter(this,new FoodModel()); } public int Calories { get { return (string.IsNullOrEmpty(txtCalories.Text)) ? 0 : Int32.Parse(txtCalories.Text); } } public int Fiber { get { return (cmbFiber.Text == "4 or more") ? 4 : (string.IsNullOrEmpty(cmbFiber.Text)) ? 0 :Int32.Parse(cmbFiber.Text); } } public float Fat { get { return (string.IsNullOrEmpty(txtFat.Text)) ? 0 : float.Parse(txtFat.Text); } } public int Points { set { ShowPointsNotification(value); } } public event EventHandler DataChanged; private void mnuExit_Click(object sender, EventArgs e) { this.Close(); } private void mnuCalculate_Click(object sender, EventArgs e) { if (DataChanged != null) this.DataChanged(sender, e); _Presenter.OnCalculatePoints(); } private void mnuClear_Click(object sender, EventArgs e) { txtCalories.Text = string.Empty; txtFat.Text = string.Empty; cmbFiber.Text = "0"; } private void ShowPointsNotification(int points) { _Notification = new NotificationWithSoftKeys { Text = String.Format("Total Points:{0}", points), Caption = "Weight Watchers Point Calculator", RightSoftKey = new NotificationSoftKey(SoftKeyType.Dismiss, "Dismiss"), }; _Notification.RightSoftKeyClick+=new EventHandler(_Notification_RightSoftKeyClick); _Notification.Visible = true; } void _Notification_RightSoftKeyClick(object sender, EventArgs e) { if (_Notification == null) return; _Notification.Visible = false; _Notification = null; } }}
Now, when it is all put together, it looks like so.
Below is a link to the source code. The project was done using Visual Studio 2008 against the windows mobile 5 sdk. It will also work against windows mobile 6 sdk, I just chose version 5 since that is the common sdk. Thanks for reading!!

[DEV]Any one heard about BatteryStatusImpl class from private api

Any android gurus out there who have used this class previously ???
I instantiate the class using the following code:
Code:
IBatteryStats mIStats = IBatteryStats.Stub.asInterface(
ServiceManager.getService("batteryinfo"));
byte[] data = null;
try {
data = mIStats.getStatistics();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Parcel parcel = Parcel.obtain();
parcel.unmarshall(data, 0, data.length);
parcel.setDataPosition(0);
BatteryStatsImpl mStats = BatteryStatsImpl.CREATOR.createFromParcel(parcel);
but BatteryStatsusImpl writesin the log:
File corrupt: battery history buffer too large (a big num)
and nothing happens the app just stops responding
and no Battery Data Available is displayed
through the debugger i got to know that the batteryinfo service returned data but still no result
I use the restricted apis as is in the AP14 android git without any modification
what do I do? please help i need to get per app battery usage.

Service terminates when app terminates

I am currently trying to implement an app that has a service running until the user explicitly ends it via the app. I would like the service to remain on otherwise. My current problem is that whenever the app is removed from the recent apps, it terminates the service as well. I have tried using START_STICKY in my onStartCommand but it doesn't change anything.
Code:
public class TriggerService extends Service{
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
and here is my code for when I call the service:
Code:
public void startServ(boolean state){
editor = sp.edit();
if (state == true) {
startService(new Intent(currentActivity, TriggerService.class));
editor.putBoolean("service_status", true);
toast = Toast.makeText(currentActivity, "Service Running", Toast.LENGTH_SHORT);
toast.show();
} else {
stopService(new Intent(currentActivity, TriggerService.class));
editor.putBoolean("service_status", false);
toast = Toast.makeText(currentActivity, "Service Not Running", Toast.LENGTH_SHORT);
toast.show();
}
editor.commit();
}
EDIT: I tried adding
Code:
android:isolatedProcess="true"
to the manifest but it didn't help. I tried a few things that were recommended over here but so far no dice
Check this article, it also suggests a potential solution
http://www.androidpolice.com/2014/03/07/bug-watch-stopping-apps-on-android-4-4-2-can-silently-kill-related-background-services-a-fix-is-on-the-way/
And this open issue
https://code.google.com/p/android/issues/detail?id=63793
painlessDeath said:
Check this article, it also suggests a potential solution
http://www.androidpolice.com/2014/0...ated-background-services-a-fix-is-on-the-way/
And this open issue
https://code.google.com/p/android/issues/detail?id=63793
Click to expand...
Click to collapse
You are a god send. Tested the app on JB and the service stayed when I closed the app. Thank god.

setActualDefaultRingtoneUri(,RingtoneManager.TYPE_ RING,) not work on s7 edge

Hi guys, could anyone help me with this?
I am trying to develop an application that could automatic change the ringtone for incoming calls, because all the existed applications which has this feature could not works well on my Galaxy S7 Edge,
but then I found out is't not that easy to change ringtone on Galaxy S7 Edge.
I am tried with these code:
File sdFile = new File("/mnt/storage/26D9-150C/test.mp3");
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, sdFile.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, sdFile.getName());
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/*");
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
values.put(MediaStore.Audio.Media.IS_ALARM, false);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
Uri uri = MediaStore.Audio.Media.getContentUriForPath(sdFile.getAbsolutePath());
getContentResolver().delete(uri ,null ,null);//if not delete, maybe it will cause some error.
Uri newUri = this.getContentResolver().insert(uri, values);
RingtoneManager.setActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE, newUri);
These code works fine on other devices, also on the Galaxy S7 Edge, you can see the new ringtone with code below, the ringtone changed into the target file, but when you received a phone call it's not the the ringtone that I set ! It's still the old ringtone before I run that code above. What's the problem ????? And I checked the ringtone from "Setting-Sound and vibrate-ringtone-incoming ringtone" it's never changed!!!
And I have granted the WRITE_SETTINGS permission already.
private Uri getSystemDefaultRingtoneUri() {
return RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE);//RingtoneManager.TYPE_ALL
}
private String getRealPath(Uri fileUrl) {
String fileName = null;
Uri filePathUri = fileUrl;
if (fileUrl != null) {
if (fileUrl.getScheme().toString().compareTo("content") == 0) {
Cursor cursor = mContext.getContentResolver().query(fileUrl, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
fileName = cursor.getString(column_index);
if (!fileName.startsWith("/mnt")) {
fileName = "/mnt" + fileName;
}
cursor.close();
}
} else if (fileUrl.getScheme().compareTo("file") == 0) {
fileName = filePathUri.toString().replace("file://", "");
if (!fileName.startsWith("/mnt")) {
fileName += "/mnt";
}
}
}
return fileName;
}
Then I searched everywhere, and find out that it seems samsung changed the system, the TYPE_RINGTONE will not effect on samsung anymore, is it true ? How could fix this problem ?
Why samsung change it like this ? It's really ****ty for developers!
Could anyone help me ? Thank you!
And here is all the code:
public class ActivityMain extends AppCompatActivity {
private static final boolean d = true;
private Context mContext;
@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
initView();
checkMyPermission(false);
}
private boolean checkMyPermission(boolean isSecondTimeCheck) {
String dialogTitle = "need WRITE_SETTINGS permission";
if (isSecondTimeCheck) dialogTitle = "you deny the permission";
String btnTitle = "ok", if (isSecondTimeCheck) btnTitle = "try again";
if (Build.VERSION.SDK_INT >= 23) {
if (!Settings.System.canWrite(this)) {
new AlertDialog.Builder(mContext).setMessage(dialogTitle).setPositiveButton(btnTitle, new DialogInterface.OnClickListener() {
 @override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_PERMISSION);
}
}).setNegativeButton("cancel", null).create().show();
return false;
}
return true;
} else {
int hasWriteContactsPermission = ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_SETTINGS);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
new AlertDialog.Builder(mContext).setMessage(dialogTitle).setPositiveButton(btnTitle, new DialogInterface.OnClickListener() {
 @override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_PERMISSION);
}
}).setNegativeButton("cancel", null).create().show();
return false;
} else {
return true;
}
}
}
private void initView() {
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
 @override
public void onClick(View view) {
//TODO I added the event here, it's more easier......this is the automatic method
// Log.d("tag", "original ringtone before set new ringtone" + getRealPath(getSystemDefaultRingtoneUri()));
// setMyRingtone("/mnt/storage/26D9-150C/0_MyFiles/8.Others/New_Eng_Rings_15.09.03/Blame it on me - akon - A.mp3");
// //setMyRingtone("/mnt/storage/26D9-150C/0_MyFiles/8.Others/New_Eng_Rings_15.09.03/Birthmark - akon - A.mp3");
//TODO here is the 2nd method, manual setting also not work....
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Choose the new ringtone");
startActivityForResult(intent, REQUEST_CODE_CHOOSE_RINGTONE_BY_USER);
}
});
}
private static final int REQUEST_CODE_PERMISSION = 1;
private static final int REQUEST_CODE_CHOOSE_RINGTONE_BY_USER = 2;
private void setMyRingtone(String path) {
File sdFile = new File(path);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, sdFile.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, sdFile.getName());
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/*");
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
values.put(MediaStore.Audio.Media.IS_ALARM, false);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
Uri uri = MediaStore.Audio.Media.getContentUriForPath(sdFile.getAbsolutePath());
getContentResolver().delete(uri, null, null);
Uri newUri = this.getContentResolver().insert(uri, values);
RingtoneManager.setActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE, newUri);
Log.d("tag", "new ringtone has been set:" + getRealPath(getSystemDefaultRingtoneUri()));//you can see that the new ringtone has been set success!
}
private Uri getSystemDefaultRingtoneUri() {
return RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE);//RingtoneManager.TYPE_ALL
}
private String getRealPath(Uri fileUrl) {
String fileName = null;
Uri filePathUri = fileUrl;
if (fileUrl != null) {
if (fileUrl.getScheme().toString().compareTo("content") == 0) {
Cursor cursor = mContext.getContentResolver().query(fileUrl, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
fileName = cursor.getString(column_index);
if (!fileName.startsWith("/mnt")) {
fileName = "/mnt" + fileName;
}
cursor.close();
}
} else if (fileUrl.getScheme().compareTo("file") == 0) {
fileName = filePathUri.toString().replace("file://", "");
if (!fileName.startsWith("/mnt")) {
fileName += "/mnt";
}
}
}
return fileName;
}
/* 当设置铃声之后的回调函数 */
 @override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_PERMISSION:
checkMyPermission(true);
break;
case REQUEST_CODE_CHOOSE_RINGTONE_BY_USER:
if (resultCode == RESULT_OK) {
try {
Uri pickedUri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
if (pickedUri != null) {
Log.d("tag", "new ringtone will be set into:" + getRealPath(pickedUri));
RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE, pickedUri);
Log.d("tag", "new ringtone has been set into:" + getRealPath(getSystemDefaultRingtoneUri()));
}
} catch (Exception e) {
if (d) e.printStackTrace();
}
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
}
Please help, thank you.
is anyone could help ?
help....
You need the
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
Permission. Only grantable for System apps.
nicholaschum said:
You need the
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
Permission. Only grantable for System apps.
Click to expand...
Click to collapse
Thanks for your reply.
I have this permission in my manifest.xml already.
It seems samsung ringtong not use the standard database...
Cooper.G said:
Thanks for your reply.
I have this permission in my manifest.xml already.
It seems samsung ringtong not use the standard database...
Click to expand...
Click to collapse
As I said, your app must be a system app (or a privileged app). Or else, adding this manifest to a normal app will not function at all and is useless.
nicholaschum said:
As I said, your app must be a system app (or a privileged app). Or else, adding this manifest to a normal app will not function at all and is useless.
Click to expand...
Click to collapse
Actually I think it's not the metter about the permission, the permission has been authorized, and the ringtone really changed into my ringtone on my device,
use these code you can see the default ringtone has changed after set.
private Uri getSystemDefaultRingtoneUri() {
return RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE);//RingtoneManager.TYPE_ALL
}
Also use a different application to check the default ringtone, it's changed into the one that I choosen.
But in fact the the ring of incoming call from the speaker never changed.
So I think samsung use a different ringtone database or whatever.
Oh, and all kinds of random ringtong tools not work on S7edge.
I will try to figure it out when I rooted my s7edge.
And before this, I found some information about samsung ring of alarm, so I think the call maybe the same reason, http://bbs.anzhuo.cn/thread-938419-1-1.html
anyway, thanks for reply.
nicholaschum said:
As I said, your app must be a system app (or a privileged app). Or else, adding this manifest to a normal app will not function at all and is useless.
Click to expand...
Click to collapse
And here is the way for android 6.0.1 to ask the WRITE_SETTINGS permission
private boolean checkMyPermission(boolean isSecondTimeCheck) {
String dialogTitle = "need WRITE_SETTINGS permission";
if (isSecondTimeCheck) dialogTitle = "you deny the permission";
String btnTitle = "ok", if (isSecondTimeCheck) btnTitle = "try again";
if (Build.VERSION.SDK_INT >= 23) {
if (!Settings.System.canWrite(this)) {
new AlertDialog.Builder(mContext).setMessage(dialogTit le).setPositiveButton(btnTitle, new DialogInterface.OnClickListener() {
 @override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_PERMISSION);
}
}).setNegativeButton("cancel", null).create().show();
return false;
}
return true;
} else {
int hasWriteContactsPermission = ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_SETTINGS);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
new AlertDialog.Builder(mContext).setMessage(dialogTit le).setPositiveButton(btnTitle, new DialogInterface.OnClickListener() {
 @override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_PERMISSION);
}
}).setNegativeButton("cancel", null).create().show();
return false;
} else {
return true;
}
}
}
Cooper.G said:
Actually I think it's not the metter about the permission, the permission has been authorized, and the ringtone really changed into my ringtone on my device,
use these code you can see the default ringtone has changed after set.
private Uri getSystemDefaultRingtoneUri() {
return RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE);//RingtoneManager.TYPE_ALL
}
Also use a different application to check the default ringtone, it's changed into the one that I choosen.
But in fact the the ring of incoming call from the speaker never changed.
So I think samsung use a different ringtone database or whatever.
Oh, and all kinds of random ringtong tools not work on S7edge.
I will try to figure it out when I rooted my s7edge.
And before this, I found some information about samsung ring of alarm, so I think the call maybe the same reason, http://bbs.anzhuo.cn/thread-938419-1-1.html
anyway, thanks for reply.
Click to expand...
Click to collapse
The permission has NOT been authorized. Please try to wrap your head around this. Your code is really messy.
https://github.com/android/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml#L1597
Line 1600 states that you must have built the system through same firmware signature, "preinstalled" (priv-app), appop and pre-23 API
1595 states that it has a protection level of signature meaning that if the app isn't signed with the same signature as the ROM it won't be authorized to use that permission.
You can also try "pm grant YOUR_APP_NAME android.permission.WRITE_SETTINGS" in adb shell - and you will get an error saying it isn't a grantable permission.
Finally, if your app is a downloadable app from Play Store, this is the only caveat. Unless you request root to priv-app, THIS PERMISSION ISN'T GRANTED.
Java:
private boolean checkWriteSettingsPermissions() {
String permission = "android.permission.WRITE_SETTINGS";
int res = getContext().checkCallingOrSelfPermission(permission);
return (res == PackageManager.PERMISSION_GRANTED);
}
This is simple code that allows you to check whether your app is granted the permission.
nicholaschum said:
The permission has NOT been authorized. Please try to wrap your head around this. Your code is really messy.
https://github.com/android/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml#L1597
Line 1600 states that you must have built the system through same firmware signature, "preinstalled" (priv-app), appop and pre-23 API
1595 states that it has a protection level of signature meaning that if the app isn't signed with the same signature as the ROM it won't be authorized to use that permission.
You can also try "pm grant YOUR_APP_NAME android.permission.WRITE_SETTINGS" in adb shell - and you will get an error saying it isn't a grantable permission.
Finally, if your app is a downloadable app from Play Store, this is the only caveat. Unless you request root to priv-app, THIS PERMISSION ISN'T GRANTED.
Java:
private boolean checkWriteSettingsPermissions() {
String permission = "android.permission.WRITE_SETTINGS";
int res = getContext().checkCallingOrSelfPermission(permission);
return (res == PackageManager.PERMISSION_GRANTED);
}
This is simple code that allows you to check whether your app is granted the permission.
Click to expand...
Click to collapse
Thank you for your patient.
1. I tried your code, and I was wrong about the permission, it says PERMISSION_DENIED. but I think this is not the problem for this question.
2. Did you tried my code ? The way that I asked for "WRITE_SETTINGS" is really work for ringtone, altho
Java:
private boolean checkWriteSettingsPermissions() {
String permission = "android.permission.WRITE_SETTINGS";
int res = getContext().checkCallingOrSelfPermission(permission);
return (res == PackageManager.PERMISSION_GRANTED);
}
said "PERMISSION_DENIED" , but it's really changed the ringtone ! If you not believe this, please try by yourself, and you can see from the setting - ring and vibrate - ringtone , you can see the result.
3. After several times try, I figure it out now... both way(manual and auto set by code "setMyRingtone()") of set the ringtone will work on the phone if have the permission of "Settings.System.canWrite(this)", but only work for the Ringtone of SIM 1, not work for SIM2. you can see the result form the setting page(only the ringtone for sim1 will change). if the ringtone still play the default ring of system, the problem probably is the metter of URI .
4. Before I post this thread, both way won't change the result of ringtone from the setting page of the phone, but as I said , you can see the result form another third part application.(this problem most probably is that I only use one SIM card at that time, did I put it into sim2? I don't know, already forget... but now if I put it into sim2 the ringtone form the setting page of the phone never change, but from the log of the code you can see the result is correct actually.)
5. Now the problem change into "How to create a standard URI and how to change the ringtone for SIM2". I will try to work on it.
6. Sorry for my pool English, and sorry for the "messy" code, I will improve it.
Anyway , thank you. you r the only one who helped me... Wish u luck.
Cooper.G said:
6. Sorry for my pool English, and sorry for the "messy" code, I will improve it.
Click to expand...
Click to collapse
I had the ringtone added on my MediaProvider but not set as the current one, I believe AOSP and TW deving is different.
When I mentioned "messy" I meant just copying and pasting the code into the forum, use
Code:
tags next time so it formats perfectly! :good::highfive:
nicholaschum said:
I had the ringtone added on my MediaProvider but not set as the current one, I believe AOSP and TW deving is different.
When I mentioned "messy" I meant just copying and pasting the code into the forum, use
Code:
tags next time so it formats perfectly! :good::highfive:
Click to expand...
Click to collapse
Thank you !
Cooper.G said:
Thank you for your patient.
1. I tried your code, and I was wrong about the permission, it says PERMISSION_DENIED. but I think this is not the problem for this question.
2. Did you tried my code ? The way that I asked for "WRITE_SETTINGS" is really work for ringtone, altho
Java:
private boolean checkWriteSettingsPermissions() {
String permission = "android.permission.WRITE_SETTINGS";
int res = getContext().checkCallingOrSelfPermission(permission);
return (res == PackageManager.PERMISSION_GRANTED);
}
said "PERMISSION_DENIED" , but it's really changed the ringtone ! If you not believe this, please try by yourself, and you can see from the setting - ring and vibrate - ringtone , you can see the result.
3. After several times try, I figure it out now... both way(manual and auto set by code "setMyRingtone()") of set the ringtone will work on the phone if have the permission of "Settings.System.canWrite(this)", but only work for the Ringtone of SIM 1, not work for SIM2. you can see the result form the setting page(only the ringtone for sim1 will change). if the ringtone still play the default ring of system, the problem probably is the metter of URI .
4. Before I post this thread, both way won't change the result of ringtone from the setting page of the phone, but as I said , you can see the result form another third part application.(this problem most probably is that I only use one SIM card at that time, did I put it into sim2? I don't know, already forget... but now if I put it into sim2 the ringtone form the setting page of the phone never change, but from the log of the code you can see the result is correct actually.)
5. Now the problem change into "How to create a standard URI and how to change the ringtone for SIM2". I will try to work on it.
6. Sorry for my pool English, and sorry for the "messy" code, I will improve it.
Anyway , thank you. you r the only one who helped me... Wish u luck.
Click to expand...
Click to collapse
Hey Have you found the solution..?

error: package com.google.android.maps does not exist

Hi,
i develop a map-app and want to implement google maps search
i get following build error
"error: package com.google.android.maps does not exist"
i develop under "android studio 3.1.3"
Hint for solution were appreciated
thanks
You need to add a reference to the maps package in build.gradle
Sent from my Z2_PRO using Tapatalk
i tested this https://stackoverflow.com/questions...le-android-maps-does-not-exist-android-studio
but without success
Can you post the content of your build.gradle file?
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.tux.myapplication"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'
implementation 'com.google.android.gmslay-services-maps:15.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
elvis61 said:
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.tux.myapplication"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'
implementation 'com.google.android.gmslay-services-maps:15.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
Click to expand...
Click to collapse
Apologies for the late reply, didn't get a notification from the thread.
Try removing the lines:
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.google.android.gmslay-services-maps:15.0.1
And add
implementation 'com.google.android.gmslay-services-maps:16.0.0'
If that doesn't work I'll draw up a demo app - this is a bit odd as I'm actually using maps in an app for my uni coursework and it's working fine
Edit: Also check that you have added the Google maven repo in the top level build.gradle file
hi,
i have still same error. i explained abov my purpose. i try this suggestion
https://stackoverflow.com/questions...ment-google-maps-search-by-address-in-android
and get this error.
and here is next purpose
https://stackoverflow.com/questions...-name-on-google-map-android?noredirect=1&lq=1
i don't know which one is better. i mean which one i can build without error.
hi jonny,
i have now a version it can work for me. but any thing is missed. can you pls add the missing parts.
thanks
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker and move the camera
setContentView(R.layout.activity_place);
EditText geoName = (EditText) findViewById(R.id.geoName);
String sGeoName = geoName.getText().toString();
LatLng geoPlace = getLocationFromAddress(this, sGeoName);
mMap.addMarker(new MarkerOptions().position(geoPlace).title(sGeoName));
mMap.moveCamera(CameraUpdateFactory.newLatLng(geoPlace));
}
/**
*
* @param context
* @param strAddress
* @return
*/
public LatLng getLocationFromAddress(Context context, String strAddress) {
Geocoder coder = new Geocoder(context);
List<Address> address;
LatLng p1 = null;
try {
// May throw an IOException
address = coder.getFromLocationName(strAddress, 5);
if (address == null) {
return null;
}
Address location = address.get(0);
p1 = new LatLng(location.getLatitude(), location.getLongitude());
} catch (IOException ex) {
ex.printStackTrace();
}
return p1;
}
}
hi jonny,
i have now a version it can work for me. but any thing is missed. can you pls add the missing parts.
thanks
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker and move the camera
setContentView(R.layout.activity_place);
EditText geoName = (EditText) findViewById(R.id.geoName);
String sGeoName = geoName.getText().toString();
LatLng geoPlace = getLocationFromAddress(this, sGeoName);
mMap.addMarker(new MarkerOptions().position(geoPlace).title(sGeoName));
mMap.moveCamera(CameraUpdateFactory.newLatLng(geoPlace));
}
/**
*
* @param context
* @param strAddress
* @return
*/
public LatLng getLocationFromAddress(Context context, String strAddress) {
Geocoder coder = new Geocoder(context);
List<Address> address;
LatLng p1 = null;
try {
// May throw an IOException
address = coder.getFromLocationName(strAddress, 5);
if (address == null) {
return null;
}
Address location = address.get(0);
p1 = new LatLng(location.getLatitude(), location.getLongitude());
} catch (IOException ex) {
ex.printStackTrace();
}
return p1;
}
}
briefly i will edit place name and move the camera. easy. but not for a newbie. pls support me.

Categories

Resources