I am trying to create an app which enters a log message when I make an outgoing call.
However, when I run the code, I get a permission denial, despite the fact that I have entered in the permissions.
Denial Log:
"09-04 02:35:50.535 1294-1666/? W/BroadcastQueue﹕ Permission Denial: receiving Intent { act=android.intent.action.NEW_OUTGOING_CALL flg=0x10000010 (has extras) } to samples.varma.packagecom.testreceive2/.CallReceiver requires android.permission.PROCESS_OUTGOING_CALLS due to sender android (uid 1000)"
Manifest Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="samples.varma.packagecom.testreceive2" >
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:enabled="true"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".CallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
</application>
</manifest>
And here is the code for my receiver:
package samples.varma.packagecom.testreceive2;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
public class CallReceiver extends BroadcastReceiver {
public CallReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (state == null) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.i("TAG", "Outgoing Number: " + number);
} else if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.i("TAG", "Incoming Number: " + number);
}
}
}
I am very new to this so there is a good chance that there are several errors or I am completely off base. Regardless I would greatly appreciate any guidance. Would anyone know why I am getting this denial?
Thanks
Edit:
It is also giving me these permission denials even though I have added the phone state permission.
The privileged phone-state permission is a system permission so I cannot add.
09-04 04:36:03.249 1294-1440/? W/BroadcastQueue﹕ Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } to samples.varma.packagecom.testreceive2/.CallReceiver requires android.permission.READ_PRIVILEGED_PHONE_STATE due to sender android (uid 1000)
09-04 04:36:03.271 1294-1308/? W/BroadcastQueue﹕ Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } to samples.varma.packagecom.testreceive2/.CallReceiver requires android.permission.READ_PHONE_STATE due to sender android (uid 1000)
1294-1308/? W/BroadcastQueue﹕ Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } to samples.varma.packagecom.testreceive2/.CallReceiver requires android.permission.READ_PHONE_STATE due to sender android (uid 1000)
I have launched the same application on Android emulator and nothing helped, even
android:enabled="true"
android:exported="true"
The solution was to go to Settings->Apps -> MyApplication -> Permissions -> Toggle Phone Permission on.
Android Phone Permission for Application
I got it to work by following this link closely Intercepting outgoing call - what am I missing? (thanks ajit)
I ended up taking off the PHONE_STATE permission, adding android:enabled="true" and android:exported="true" to my receiver in the manifest, relocating the NEW_OUTGOING_CALL permission to below application(not sure if this is necessary), taking away the intended sdk versions and basically copying the receiver from the link.
Updated manifest code from receiver tag to manifest tag is:
<receiver
android:name=".testreceive3"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>-->
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />>-->
</manifest>
U need to apply the runtime permission int your code when your code running on Android 6.0 or above.
You should add the following thing in your Manifest receiver
<service android:name=".CallReceiver"
android:enabled="true"
android:exported="false" >
</service>
Use permission CALL_PHONE instead of OUTGOING
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Best solution is when you run the code activate usb debugging, make sure you select disable permissions monitor settings in developer settings ! App wont be asked for permissions by the OS anymore. Happy helping :)
This will work without changing anything in manifest!
Related
My final goal is to easily activate and deactivate a certain series of 17 alarms in the clock app whenever necessary. Unfortunately, the app only offers the option to either deleting(!) all alarms at once or deactivating one by one. The same applies to every other app from the Play Store I have tried.
I think an acceptable workaround solution would be to delete all alarms with the mentioned functionality and re-implement the series of alarms programmatically as needed. So, I wrote a minimalist app in Android Studio that works perfectly fine in the emulator.
After building the debug APK, I transferred it on my smartphone and installed it without any errors. Now I am facing the problem that after starting my app only the first alarm is created. Does somebody have an explanation for this error. Thank you!
MainActivity.java
package com.example.setalarms;
import android.app.Activity;
import android.content.Intent;
import android.provider.AlarmClock;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.Arrays;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] messages = {"alarm1","alarm2to16","alarm17"};
int[] hours = {7,8,9};
int[] minutes = {0,0,0};
ArrayList<Integer> days = new ArrayList<>(
Arrays.asList(1,2,3,4,5,6,7)
);
Intent[] intents = new Intent[messages.length];
for (int i = 0; i < messages.length; i++) {
Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
.putExtra(AlarmClock.EXTRA_MESSAGE, messages[i])
.putExtra(AlarmClock.EXTRA_HOUR, hours[i])
.putExtra(AlarmClock.EXTRA_MINUTES, minutes[i])
.putExtra(AlarmClock.EXTRA_DAYS, days)
.putExtra(AlarmClock.EXTRA_SKIP_UI, i != messages.length - 1);
intents[i] = intent;
}
startActivities(intents);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.SetAlarms"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application>
</manifest>
Hardware / Software
SAMSUNG Galaxy A3 (2017) SM-A320FL
Android Studio Dolphin 2021.3.1 Patch 1
Android 8.0.0 (Oreo)
Clock 7.0.92.7 (Galaxy Store)
I'm writing a Android app and there's a strange behavior related to FusedLocationApi.requestLocationUpdates() that I've searched on SO and none of the other related questions solved my problem.
Apparently the requestLocationUpdates do not trigger the onLocationChanged() method all the times; I'm saying this because I'm cleaning my app's data on emulator for each run and sometimes the onLocationChanged() is triggered, sometimes not (most of under some conditions like run the app for the second time w/o cleaning the app's data or after making a user data's wipe i.e)
Below you can find my code (links from pastebin, I don't want to create any visual overload here)
Main Activity: http://pastebin.com/XiRrcR11
MapHandler: http://pastebin.com/HELnhaxy
Another problem is, oddly enough, if I use a anonymous inner class in the MapHandler in the method displayLocation(), the app works, but if I use a external class who extends LocationListener the app do not behave correctly
I know the expected question levels in SO are high but I'm starting my studies about Android development and this issue is taking my sleep away
Btw here is my AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.trackit.app.track_it_v002">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.INTERNET" />
<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.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Can you guys give me a hand here?
EDIT: after some debugging I've seen the requestLocationUpdates is not returning a non null object and not triggering onLocationChanged(), anyone have a idea why? =S
I encountered this issue. The mGoogleApiClient object, which needs to be connected at the time of requestLocationUpdates. This was resolved by requestingLocationUpdates from onConnected callback.
/*
* Called first time google client is connected
*/
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.v(LOG_TAG,"DetectDrivingService - onConnected");
// Create
try {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
catch(SecurityException se){
}
}
Before labeling this as a duplicate:
I've read at least 15 similar threads and each and every one is either using the old Parse code (the now deprecated setDefaultPushCallback) or the problem was a result of calling Parse.initialize(...) in an activity and not in the Application class. But this is not applicable to my case. The official example (which I'm using) is evidently doing it right, so the code is already in the Application class.
I've downloaded the Push Starter example from Parse's official guides and tried it out on an emulator. I receive pushes only while the app is running. The moment's it's closed (removed from the "recent apps" list, not force killed), I no longer get pushes. Which makes the entire feature rather useless... I tried with and without GCM, the behavior is the same.
Any clues what could possible be wrong? All classes are the stock example ones, nothing overridden or added by me (except for the id/key and the ParsePush.subscribeInBackground call which I copied from the guide). Weirdly enough, the example code did not contain ParsePush.subscribeInBackground and the QuickStart does not mention it. It even gives a Test button that supposedly sends a push which I never receive, with or without subscribeInBackground. The only way I've been able to get a push so far was with subscribeInBackground and sending a push manually though the web console, and only so if the app is running. The web console also keeps telling there's 2 registered devices... which is untrue.
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.parse.starter"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!--
IMPORTANT: Change "com.parse.starter.permission.C2D_MESSAGE" in the lines below
to match your app's package name + ".permission.C2D_MESSAGE".
-->
<permission android:protectionLevel="signature"
android:name="com.parse.starter.permission.C2D_MESSAGE" />
<uses-permission android:name="com.parse.starter.permission.C2D_MESSAGE" />
<application
android:name=".ParseApplication"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:allowBackup="true">
<activity
android:name=".ParseStarterProjectActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.ParsePushBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<!--
IMPORTANT: Change "com.parse.starter" to match your app's package name.
-->
<category android:name="com.parse.starter" />
</intent-filter>
</receiver>
</application>
</manifest>
ParseApplication:
package com.parse.starter;
...
public class ParseApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// Initialize Crash Reporting.
ParseCrashReporting.enable(this);
// Enable Local Datastore.
Parse.enableLocalDatastore(this);
ParseUser.enableAutomaticUser();
// Add your initialization code here
Parse.initialize(this, "***", "***");
ParseACL defaultACL = new ParseACL();
// Optionally enable public read access.
// defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
ParsePush.subscribeInBackground("", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push", e);
}
}
});
}
}
Just to clarify why you are seeing this behaviour, Parse has two different ways for delivering push notifications:
"Parse way": the Parse SDK has a component running in your app, which keeps a connection to the Parse backend servers. This will only work when your app is actually running, because killing it breaks the connection with the Parse backend.
GCM "Google" push notifications: This works via Google Play Services, an app which is always running in the background and that can start your app when needed. This will always work, unless you force stop the application.
In your case you are there is a package name conflict: com.parse.starter is the package name that was actually included in the example. This causes GCM not to work, because it already knows the package under a different signature. Changing your package name to something unique like com.parse.kaqqao should solve the trick.
There are a few reasons for this:
There are two BroadcastReceiver viz the "com.parse.ParsePushBroadcastReceiver" and "com.parse.GcmBroadcastReceiver". I believe that the first receiver is getting prioritized over the GCMBroadcastReceiver and thus the behavior is not affected by removing or keeping this receiver. It could also be due to action "com.parse.push.intent.RECEIVE", which might be handling the push messages RECEIVE action. If both the receiver perform the same task of parsing the Push message (starting the same service in background), then include the intent-filter inside one receiver and let it handle all kinds of push messages. Since GCMBroadcastReceiver holds the C2DM permission.
Try changing the order of the two broadcast receiver tags in the manifest. (Keep GCMBroadcastReceiver before the ParsePushBroadcastReceiver)
It could be due to android:exported="false", maybe it prevents the Receiver from listening to the push messages sent by server. Try changing to true.
Using a customer defined activity and i've declared the intent action in the manifest.xml
Here's the manifest file with the error
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="course.labs.dangerousapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="13"
android:targetSdkVersion="18" />
<!--
TODO - Using a permission element,
define a custom permission with name
"course.labs.permissions.DANGEROUS_ACTIVITY_PERM"
and "dangerous" protection level.
-->
<permission
android:name="course.labs.permissions.DANGEROUS_ACTIVITY_PERM"
android:protectionLevel="dangerous"
>
</permission>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<!-- TODO - enforce the custom permission on this Activity -->
<activity
android:permission="course.labs.permissions.DANGEROUS_ACTIVITY_PERM"
android:name=".DangerousActivity"
android:label="#string/app_name" >
<!--
TODO - add additional intent filter info so that this Activity
will respond to an Implicit Intent with the action
"course.labs.permissions.DANGEROUS_ACTIVITY"
-->
<intent-filter >
<category android:name="android.intent.category.DEFAULT" />
<action android:name="course.labs.permissions.DANGEROUS_ACTIVITY" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Here's where the intent was invoked in the program
Code:
package course.labs.permissionslab;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class GoToDangerousActivity extends Activity {
private static final String TAG = "Lab-Permissions";
private static final String DANGEROUS_ACTIVITY_ACTION = "course.labs.permissions.DANGEROUS_ACTIVITY";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.go_to_dangerous_activity);
Button startDangerousActivityButton = (Button) findViewById(R.id.start_dangerous_activity_button);
startDangerousActivityButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startDangerousActivity();
}
});
}
private void startDangerousActivity() {
Log.i(TAG, "Entered startDangerousActivity()");
startActivity(new Intent(DANGEROUS_ACTIVITY_ACTION));
}
}
Please let me know if any other info will hell, I've been tried everything i know and not sure why i'm getting this error again.
Did you installed the first App that has the manifest before calling using the second App?
[EDIT]
To check if a activity is registered to some Intent, you can use adb.exe available on Platform-tools folder to list all intents configured on the device.
To do that, on prompt execute the command below:
adb shell dumpsys package > packages.txt
Then open packages.txt and find for action name course.labs.permissions.DANGEROUS_ACTIVITY. Should have a activity associate with that action.
Try so:
startActivity(new Intent(getApplicationContext(), DANGEROUS_ACTIVITY_ACTION.class));
This is the normail way of doing it
[EDIT]
OR (note the different declaration of DANGEROUS_ACTIVITY_ACTION)
private static final String DANGEROUS_ACTIVITY_ACTION = ".DangerousActivity";
// ...
startActivity(new Intent(DANGEROUS_ACTIVITY_ACTION));
I use this in a SplashScreen Activity to call the Main Activity (after done loading my graphics from SVG files).
You need to run "DangerousApp" before running "GoToDangerousActivity".
This is because your dangerous app is not even installed on the device. If you were trying to do this from android studio, by default studio would try to launch the app which won't be successful because of the permission it needs. To install your dangerours, modify studio's launch settings to not to run the app right away. I got the same issue.
I know this has been asked ALOT on here, but I have been scouring the interwebs for hours and I have even reused some of my previous code for receiving sms' and I got...nothing.
So, here goes, basic app to receive SMS but the app never receives the intent. I thought the intent may be ignored if the text is sent from the same phone but that does not seem to be the case, as other apps pick up the text fine.
Here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.encima.smsreceiver"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainActivity" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MessageReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
</manifest>
And, here is the receiver, nothing seems to be new here, so I have no idea what the problem is:
package com.encima.smsreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class MessageReceiver extends BroadcastReceiver {
private static final String TAG = "Message recieved";
#Override
public void onReceive(Context context, Intent intent) {
Bundle pudsBundle = intent.getExtras();
Object[] pdus = (Object[]) pudsBundle.get("pdus");
SmsMessage messages =SmsMessage.createFromPdu((byte[]) pdus[0]);
Log.i(TAG, messages.getMessageBody());
Toast.makeText(context, "SMS Received : "+messages.getMessageBody(),
Toast.LENGTH_LONG).show();
}
}
The debug phone I am using is running 2.2.2 and I have other apps running that detect sms, including some of my own.
Any insight into this would be appreciated!
Thanks
Because the SMS broadcast intent is sent by
Context.sendOrderedBroadcast(...),
if any other app registers the BroadcastReceiver and calls abortBroadcast, the other receiver will not get the broadcast.
To increase the probability of your app receiving the broadcast create an IntentFilter, use IntentFilter.setPriority.
I do not know if this is your problem but you should definitelly try this:
Instead of ".MessageReceiver" put android:name = "com.encima.smsreceiver.MessageReceiver"
This is fix that workout many times for me when something doesn't get called.