I learned to define my own custom permission with different level (normal, signature, dangerous) a few hours ago. Then I followed the android documentation and this question's answered by Yury to test it in real. First I made the permission level normal and after clicking button from first activity, I can access the second activity. But when I set it dangerous, I failed to access the second activity. I got
Security exception - permission denial everytime. Then I go to 'Permission' section in the app settings and see my custom permission is turned off. I turn it on and then can access the activity.
But my question is how I can request this permission like other dangerous permission defined by android system and show dialog and grant it without going to the permission section in app settings. I know how to access permission with -
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not 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; 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.
}
} else {
// Permission has already been granted
}
But the problem is android's default permissions are defined in Manifest.permission.READ_CONTACTS but how I define my custom permission with that.
My code is given below.
PermissionTestServerActivity (First activity):-
public class PermissionTestServerActivity extends Activity {
private static final String TAG = "PermissionTestServerActivity";
/** Called when the activity is first created. */
Button btnTest;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnTest = (Button) findViewById(R.id.btnTest);
btnTest.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Button pressed!");
Intent in = new Intent();
in.setAction("com.testpackage.permissiontestclient.MyAction");
in.addCategory("android.intent.category.DEFAULT");
startActivity(in);
}
});
}
}
And its manifest :-
<?xml version="1.0" encoding="utf-8"?>
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="com.testpackage.mypermission"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".PermissionTestServerActivity"
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>
PermissionTestClient's manifest (Second activity):-
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.testpackage.permissiontestclient"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<permission android:name="com.testpackage.mypermission" android:label="my_permission" android:protectionLevel="dangerous"></permission>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:permission="com.testpackage.mypermission"
android:name=".PermissionTestClientActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter >
<action android:name="com.testpackage.permissiontestclient.MyAction" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
Related
I found the below issue of Screen Overlay detected when click permission in Motog3 marshmallow mobile.
i found many solution over internet search everywhere, you can check below:
Remove esfile explorer
https://www.youtube.com/watch?v=QHidevTDrYI
Screen overlay detected blocks Android permissions
https://android.stackexchange.com/questions/148260/screen-overlay-detected-what-is-the-problem
https://forums.androidcentral.com/android-6-0-marshmallow/682802-screen-overlay-detected-what-can-i-do.html
https://www.howtogeek.com/271519/how-to-fix-the-screen-overlay-detected-error-on-android/
https://github.com/MohammadAdib/Roundr/issues/10
Android marshmallow : Galaxy Note 4 Screen Overlay Detected
etc. many more.
If i don't call permission below then no problem.
Therefore if anyone want to give the best solution then please share.
Please before mentioning it duplicate, i want proper solution for it.
Feel free to ask any information or code i'm sharing some code also.
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.psm">
<!---->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/logo"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/MyMaterialTheme">
<activity android:name=".MainActivity"
android:screenOrientation="portrait">
</activity>
<activity android:name=".SplashScreen"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.nippon.registration.Registration"
></activity>
</application>
</manifest>
Permission code in Mainactivity.java
checkAndRequestPermissions(); //called in oncreate() of activity
private boolean checkAndRequestPermissions() {
try {
int permissionWriteEXTERNALSTORAGE = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
int PermissionCamera = ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA);
List<String> listPermissionsNeeded = new ArrayList<>();
if (permissionWriteEXTERNALSTORAGE != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (PermissionCamera != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.CAMERA);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), 1);
return false;
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
Thanks in advance, for perfect solution.
finally i got solution for above problem of Screen Overlay Detected
by removing below code which i was using for testing memory usage in app:
final Runtime runtime = Runtime.getRuntime();
final long usedMemInMB=(runtime.totalMemory() - runtime.freeMemory()) / 1048576L;
final long maxHeapSizeInMB=runtime.maxMemory() / 1048576L;
final long availHeapSizeInMB = maxHeapSizeInMB - usedMemInMB;
Toast.makeText(getApplicationContext(),String.valueOf(usedMemInMB+" "+ maxHeapSizeInMB+" "+ availHeapSizeInMB), Toast.LENGTH_LONG).show();
Thanks for everyone support!
I want to ask users to agree with the disclaimer that I have provided in my application, and then if they agreed, next time they are using the app, we just re-show them the disclaimer for a few seconds without asking to click on anything and redirect them to the application. The best way I could have come up with it was, using a custom permission and however I did add permission commands to my manifest I could not figure out how to actually activate the permission in my code:
import java.util.jar.Manifest;
public class Language extends Activity {
Button engBut, fraBut;
// public static int j;
public void click (View view){
// j=1;
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
startActivity(intent);
}
public void fraClick (View view){
// j=2;
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
startActivity(intent);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_language);
ImageView logo = (ImageView) findViewById(R.id.logo);
ImageView montfortLogo = (ImageView) findViewById(R.id.montfortLogo);
montfortLogo.setImageResource(R.drawable.k);
logo.setImageResource(R.drawable.j);
engBut = (Button) findViewById(R.id.engBut);
engBut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(Language.this);
builder.setCancelable(true);
builder.setTitle("DISCLAIMER");
builder.setMessage(R.string.result_disclaimer);
builder.setNegativeButton("Get me out of here.", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
builder.setPositiveButton("I agree.", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
intent.setAction("com.techideas4you.pharamacy.MyAction");
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
}
});
builder.show();
}
});
fraBut = (Button) findViewById(R.id.fraBut);
Log.i("Locale", String.valueOf(Locale.getDefault()));
}
}
This was my first page code.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="example.ex"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
<permission android:name="testDisclaimer" android:label="DISCLAIMER"
android:description="#string/result_disclaimer"/>
<uses-permission android:name="testDisclaimer"/>
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="#drawable/icon"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="#string/app_name">
</activity>
<activity
android:name=".ActivityQuestion"
android:icon="#drawable/home"
android:label="Home"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<activity
android:name=".ActivityResult"
android:icon="#drawable/home"
android:label="Home"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<activity android:name=".Language">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter >
<action android:name="com.techideas4you.pharamacy.MyAction"
/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
and this is my manifest if anybody could help me out here I really appreciate it.
You have to add android:protectionLevel="dangerous" to the declaration of your permission else it will be granted automatically and users will not be presented with a dialog although you call requestPermission().
<permission android:name="your.package.name.permission.testDisclaimer" android:label="DISCLAIMER"
android:description="#string/result_disclaimer"
android:protectionLevel="dangerous"/>
<uses-permission android:name="your.package.name.permission.testDisclaimer"/>
In order to have the runtime show the disclaimer, you have to call
requestPermissions(new String[]{"your.package.name.permission.testDisclaimer"}, 42);
The result (whether user agreed) will be transmitted to you in onRequestPermissionsResult()
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 42 && grantResults != null){
Toast.makeText(this, "Permission " + permissions[0] + (grantResults[0] == PERMISSION_GRANTED ? "" : " NOT ") + " granted! ", Toast.LENGTH_LONG).show();
}
}
Please note that by using the permission system, you also have to cope with the fact that users will NOT be shown the permission-request-disguised-as-disclaimer if they
[...] turned down the permission request in the past and chose the
Don't ask again option in the permission request system dialog [...]
(quoted from documentation).
So maybe simply writing a flag to SharedPreferences will do the job just as well.
public class MainActivity extends BroadcastReceiver {
WebView web1;
WebView web2;
Button btn;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
Log.i("U", "Action" + action);
}
}
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BROADCAST_PACKAGE_REMOVED"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.example2.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>
</application>
This code i have to Get Information on log-cat if user Uninstall there action take place
But in manifest file it is showing :
it showing Error : Permission is only granted to system apps how i will Fix this issue please help any other way to know that user Uninstall application from device .
From the documentation:
public static final String BROADCAST_PACKAGE_REMOVED
Allows an application to broadcast a notification that an application package has been removed.
It appears that you don't need this permission to just receive the broadcast.
i am trying to develop a android application using broadcast receiver,my application means that,first i want to define and store a PARENT number to the database on my first activity ,when we install the app this activity will launch and the parent number saved to the database,then broadcast receiver want to active and its listen for call state changing,if any call is make through that phone i want to send a message to the parent number...??...here how can i use broadcast receiver...is it possible...and i mentioning my codes below......i hope you can help me for this .i try to do this many ways but i cant get the result.here first i create my first activity inside that i accessing my database values and trying to activate broadcast receiver.
public class PARENT_CALLActivity extends Activity
{
String PARENT=null;
EditText edparent;
Button submit;
String parent_number;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
edparent=(EditText)findViewById(R.id.editText1);
submit=(Button)findViewById(R.id.btnsubmit);
submit.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
PARENT=edparent.getText().toString();
MyDabasehandler db=new MyDabasehandler(getApplicationContext());
if(db.getContact().equals(null))
{
db.addContact(new Contacts(PARENT));
}
else
{
db.editContact();
}
Intent reciver=new Intent(getApplicationContext(),myBroadcast.class);
startActivity(reciver);
}
});
}
}
my broadcast receiver....
public class myBroadcast extends BroadcastReceiver
{
String out_number;
String myparent;
#Override
public void onReceive(Context context, Intent intent)
{
// TODO Auto-generated method stub
out_number=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
MyDabasehandler db=new MyDabasehandler(context);
myparent=db.getContact().toString();
//Toast.makeText(context, out_number+"number", Toast.LENGTH_LONG).show();
SmsManager sm=SmsManager.getDefault();
sm.sendTextMessage(myparent, "5554", "calling..to"+out_number, null, null);//5554 is my emulator number to check its in emulator
Toast.makeText(context, "send"+out_number, Toast.LENGTH_SHORT).show();
}
}
and my Manifest is..
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="sha.pcall"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".PARENT_CALLActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MyDabasehandler"
android:label="#string/app_name">
</activity>
<activity android:name=".Contacts"
android:label="#string/app_name">
</activity>
<receiver android:name=".myBroadcast"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
/manifest>
and i am getting force to close when i press the submit button.
You should put the LogCat output that shows the exception StackTrace.
What I can spot in the code that it seems that you are missing
<uses-permission android:name="android.permission.READ_PHONE_STATE" >
I am trying to send an Intent from the onCreate in an Activity to start an IntentService. However the IntentService's onHandleIntent is never being received. I have tried changing around the Manifest with Intent-filters but nothing seems to be working. No exceptions are being thrown, but the IntentService is simply not called.
Here is the onCreate
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db = new TwitterDB(this);
String[] columns = new String[1];
columns[0] = TwitterDB.TEXT;
tAdapter = new SimpleCursorAdapter(this, 0, null, columns, null, 0);
tweets = (ListView)findViewById(R.id.listtwitter);
tweets.setAdapter(tAdapter);
Intent intent = new Intent(this, SyncService.class);
intent.putExtra("action", SyncService.TWITTER_SYNC);
this.startService(intent);
}
Here is the creator and onHandleIntent of the IntentService class, I know it is not being called because logcat never shows "Retrieved intent". The constructor is not called either (There was a log call in there, but I removed it.
public SyncService(){
super("SyncService");
twitterURI = Uri.parse(TWITTER_URI);
Log.i("SyncService", "Constructed");
}
#Override
public void onHandleIntent(Intent i){
int action = i.getIntExtra("action", -1);
Log.i("SyncService", "Retrieved intent");
switch (action){
case TWITTER_SYNC:
try{
url = new URL(twitterString);
conn = (HttpURLConnection)url.openConnection();
syncTwitterDB();
conn.disconnect();
}catch(MalformedURLException e){
Log.w("SyncService", "Twitter URL is no longer valid.");
e.printStackTrace();
}catch(IOException e){
Log.w("SyncService", "Twitter connection could not be established.");
e.printStackTrace();
}
break;
default:;
// invalid request
}
}
And here is the Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.twitter"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET"/>
<application android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".TwitterTwoActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<service android:name="SyncService"/>
</activity>
</application>
</manifest>
Move your service declaration outside of the scope of the TwitterTwoActivity in the XML file, as I have done here:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.twitter"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET"/>
<application android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".TwitterTwoActivity"
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="SyncService"/>
</application>
</manifest>
You need to define the path to the service in your manifest, simply putting the name is not sufficient.
Change
<service android:name="SyncService"/>
to
<service android:name=".SyncService"/>
if SyncService is in the root of your package, add respective folder before .SyncService if needed.