I made a small android app which simply sends an SMS.
I added the Send_SMS permission in the manifest.
My code looks like:
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.SEND_SMS},1);
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
sendSMS(phoneNumberTo, smsMessage);
}
return;
}
}
}
private void sendSMS(String phoneNumber, String message) {
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, null, null);
}
My phone is trying to send the SMS, but I get an error:
I should add that:
When I click on my phone "re-send" it works
I am using xiomi note 4
try this
SmsManager smsManager = SmsManager.getDefault();
ArrayList<String> parts = smsManager.divideMessage(message);
smsManager.sendMultipartTextMessage(phoneNumber, null, parts, null, null);
I think the problem is in getting the permission at run-time. This code may help you
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.SEND_SMS)) {
// 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; request the permission
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_SEND_SMS);
}
} else {
// message sending code here
}
Related
I am trying to send SMS from a service class and found the following code which sends SMS from Activity class. Getting an error on "this" in sendSMSMessage method which is quite understandable because the code for sending SMS from Activity class. How I can convert it to sending SMS from Service class? The Service class was written before, working without any issue in production. Trying to add this SMS sending code as an extra functionality.
protected void sendSMSMessage() {
phoneNo = txtphoneNo.getText().toString();
message = txtMessage.getText().toString();
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.SEND_SMS)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_SEND_SMS);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_SEND_SMS: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNo, null, message, null, null);
Toast.makeText(getApplicationContext(), "SMS sent.",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"SMS faild, please try again.", Toast.LENGTH_LONG).show();
return;
}
}
}
}
Replace this with getActivity() and Voila!
I have made an app that tracks call log in background using ContentObserver and service(runs in foreground).
Manifest.permission.CALL_PHONE
This is the permission i am checking for
if (CallTrackingHelper.isCallPermissionEnabled(appContext)) {
val task = OneoffTask.Builder()
.setService(CallLogService::class.java)
.setExecutionWindow(0, 6)
.setTag("call-track")
.setRequiredNetwork(Task.NETWORK_STATE_ANY)
.setRequiresCharging(false)
.setUpdateCurrent(true)
.build()
val mGcmNetworkManager = GcmNetworkManager.getInstance(appContext)
mGcmNetworkManager.schedule(task)
}
i start a gcmtaskservice that uploads call-log to server
override fun onRunTask(p0: TaskParams?): Int {
val callLogs = CallTrackingHelper.getCallLog(lastSyncedIndex, this)
//
}
in service i fetch contact
fun getCallLog(id: Long, service: CallLogService): ArrayList<CallLogModel> {
val callLogList = ArrayList<CallLogModel>()
if (!isCallPermissionEnabled(service)) {
return callLogList
}
var mCursor: Cursor? = null
try {
val args = arrayOf(id.toString())
if (id != 0L) {
mCursor = UCApplication
.getInstance()
.applicationContext
.contentResolver
.query(
CallLog.Calls.CONTENT_URI,
null,
"_id > ? ",
args,
null
)
} else {
mCursor = UCApplication
.getInstance()
.applicationContext
.contentResolver
.query(
CallLog.Calls.CONTENT_URI,
null,
null,
null,
CallLog.Calls._ID + " DESC" + " LIMIT 200 "
)
}
} catch (e: SecurityException) {
//
}
//
return callLogList
}
fun isCallPermissionEnabled(context: Context?): Boolean {
if (context == null || ContextCompat.checkSelfPermission(context, PERMISSIONS)
!= PackageManager.PERMISSION_GRANTED) {
return false
}
return true
}
Still i am getting lot of securityException so I have to add try and catch
You need to get run time permission in 6.0 > devices
get runtime permission like this:
final String[] NECESSARY_PERMISSIONS = new String[] {Manifest.permission.GET_ACCOUNTS };
if (ContextCompat.checkSelfPermission(DialerHomeActivity.this,
Manifest.permission.GET_ACCOUNTS) == PackageManager.PERMISSION_GRANTED) {
//Permission is granted
} else {
//ask for permission
ActivityCompat.requestPermissions(
DialerHomeActivity.this,
NECESSARY_PERMISSIONS, 123);
}
Add this to your manifest.xml above <appication> tag:
<uses-permission android:name="android.permission.READ_CALL_LOG"></uses-permission>
<uses-permission android:name="android.permission.WRITE_CALL_LOG"></uses-permission>
you can read more at : here
Issue was that if user already has an app without
<uses-permission android:name="android.permission.READ_CALL_LOG"></uses-permission>
<uses-permission android:name="android.permission.WRITE_CALL_LOG"></uses-permission>
in manifest and gives call permission or phone permission , after update if these are added in update call/phone permission is still their but call log permission is not so you need to ask again.
Fresh install was working fine for me
Have you requested permissions on runtime?
// 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.
}
}
Check this:
https://developer.android.com/training/permissions/requesting.html
I was facing the same problem. Use this code for run time permission:
private static final int PHONE_LOG = 1;
private void checkCallLogPermission() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG},PHONE_LOG);
return;
}
}
You can access all contact log for your mobile with this code
private static final int PHONE_LOG_PERMISSION= 1;
private void checkCallLogPermission() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG},PHONE_LOG_PERMISSION);
return;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == PHONE_LOG_PERMISSION) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission is granted
showContacts();
} else {
Toast.makeText(this, "Until you grant the permission, we canot display the names", Toast.LENGTH_SHORT).show();
}
}
}
I am stuck on a security issue. I am trying to send message from my android app using SMS Manager and after sending message it saves message in my Phone's inbox. But i want messages to not to be save or delete programmatically.
Here is the code which I am using:
if (ContextCompat.checkSelfPermission(Main6Activity.this,
Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
if(ActivityCompat.shouldShowRequestPermissionRationale(Main6Activity.this,
Manifest.permission.SEND_SMS)) {
}
else {
ActivityCompat.requestPermissions(Main6Activity.this,
new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_SEND_SMS);
}
}
else {
ActivityCompat.requestPermissions(Main6Activity.this,
new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_SEND_SMS);
}
#Override
public void onRequestPermissionsResult(int requestCode,String permissions[],
int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_SEND_SMS: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phone, null, "your password is
"+password, null, null);
Toast.makeText(getApplicationContext(), "SMS sent \nMake
sure you have enough balance to send message",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"SMS faild, please try again.",
Toast.LENGTH_LONG).show();
return;
}
}
}
}
Please help me.
Thanks in advance.
But i want messages to not to be save or delete programatically.
This is not possible on Android 4.4+. Only the user's chosen SMS client app can modify the contents of the Sms provider.
I made message sending app it work perfect in all version till kitkat 4.4.4 but not working in Lollipop and Marshmallow I don't understand why?
public void sendsms()
{
try
{
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNo, null,smsmessage, null, null);
printmsg(1);
}
catch (Exception e)
{
printmsg(0);
e.printStackTrace();
}
}
public void printmsg(int a)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Information:");
if(a==1)
builder.setMessage("SMS Send Wait For Response!!!");
else
builder.setMessage("Sending Failed, Please Try Again Later!!!");
builder.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which)
{
//Toast.makeText(getApplicationContext(), "changing activity",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(ResWindow.this, Home.class);
startActivity(intent);
ResWindow.this.finish();
}
});
builder.show();
From API 23, i.e. Android Marshmallow, the app will have to ask for permissions while running instead of declaring them beforehand. The logic here is, to see if the device is below 23, if it is, then the SMS would be sent without any problem, if it 23 and above, you will have to prompt the user to allow the app to send the message.
Here is a sample code with explanation which might help you out there.
private static final int PERMISSION_REQUEST = 100;
//This is the onClick listener of 'Send SMS' button
public void send(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//This if checks if the device is API 23 or above
if (checkSelfPermission(Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
//This checks if the permission is already granted.
if (shouldShowRequestPermissionRationale(Manifest.permission.SEND_SMS)) {
//This displays a message to the user as to why do we
//need the permission. If the user accepts, we display the permission granting dialog.
Snackbar.make(findViewById(R.id.rl), "You need to grant SEND SMS permission to send sms",
Snackbar.LENGTH_LONG).setAction("OK", new View.OnClickListener() {
#Override
public void onClick(View v) {
requestPermissions(new String[]{Manifest.permission.SEND_SMS}, PERMISSION_REQUEST);
}
}).show();
} else {
//This displays the permission granting dialog directly.
requestPermissions(new String[]{Manifest.permission.SEND_SMS}, PERMISSION_REQUEST);
}
} else {
sendSMS(); // Runs if the permission is already granted.
}
} else {
sendSMS(); // Runs if the device's API is below 23.
}
}
private void sendSMS() {
//Code for sending sms.
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Snackbar.make(findViewById(R.id.rl), "Permission Granted",
Snackbar.LENGTH_LONG).show();
sendSMS();
//SMS sent
} else {
Snackbar.make(findViewById(R.id.rl), "Permission denied",
Snackbar.LENGTH_LONG).show();
//SMS not sent.
}
}
The code was taken from here. A more elaborated explanation can be found there.
I want to check how new permission model works so in app's settings I disable Contacts. Then I go to app and try to read Contacts and ... it kinda works:
try {
Uri result = data.getData();
int contentIdx;
cursor = getContentResolver().query(result, null, null, null, null);
contentIdx = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
if(cursor.moveToFirst()) {
content = cursor.getInt(contentIdx);
}
if(content > 0) {
contentIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
if(cursor.moveToFirst()) {
name = cursor.getString(contentIdx);
}
contentIdx = cursor.getColumnIndex(BaseColumns._ID);
if(cursor.moveToFirst()) {
content = cursor.getLong(contentIdx);
}
cursor = managedQuery(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[] { Phone.NUMBER }, Data.CONTACT_ID + "=?", new String[] { String.valueOf(content) }, null);
if(cursor.moveToFirst()) {
number = cursor.getString(cursor.getColumnIndex(Phone.NUMBER));
}
}
} catch (Exception e) {
//SecurityException
}
I'm able to read Contact's Name
when I try to read Contact's Number SecurityException is thrown
java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.HtcContactsProvider2 uri content://com.android.contacts/data/phones from pid=20123, uid=10593 requires android.permission.READ_CONTACTS, or grantUriPermission()
Why is that?
Related stuff: Contact data leakage via pick activities
Android marshmallow have new permissions system.
You need to request permissions at run time.
http://developer.android.com/training/permissions/requesting.html.
Example:
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.tv_contact:{
askForContactPermission();
break;
}
}
}
private void getContact(){
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
public void askForContactPermission(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.READ_CONTACTS)) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Contacts access needed");
builder.setPositiveButton(android.R.string.ok, null);
builder.setMessage("please confirm Contacts access");//TODO put real question
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#TargetApi(Build.VERSION_CODES.M)
#Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(
new String[]
{Manifest.permission.READ_CONTACTS}
, PERMISSION_REQUEST_CONTACT);
}
});
builder.show();
// Show an expanation 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(getActivity(),
new String[]{Manifest.permission.READ_CONTACTS},
PERMISSION_REQUEST_CONTACT);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}else{
getContact();
}
}
else{
getContact();
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CONTACT: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getContact();
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
ToastMaster.showMessage(getActivity(),"No permission for contacts");
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}