Show dialog over another app without SYSTEM_ALERT_WINDOW permission - java

Right now, I'm using the following permission to show a dialog over another app :
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Dialog :
dialogBuilder = new AlertDialog.Builder(activity);
LayoutInflater inflater2 = (LayoutInflater) AppController.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View dialogView = inflater2.inflate(R.layout.dialog_view, null);
dialogBuilder.setView(dialogView);
dialog = dialogBuilder.create();
dialog.setCancelable(true);
final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
final Window dialogWindow = dialog.getWindow();
if (dialogWindow != null) {
dialogWindow.setAttributes(layoutParams);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
dialogWindow.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
} else {
dialogWindow.setType(WindowManager.LayoutParams.TYPE_PHONE);
}
}
dialog.show();
Snaptube app, shows a dialog over the YouTube app without asking for any permission :
How I can achieve that?

Related

How to show dialog in service on android

In my application I want to use service and in this service I should show layout.
I want when click on button show dialog, I write below codes!
But after click on button, show this dialog back of layout and not show any dialog!
My service codes :
public class FloatingLayoutService extends Service implements StepperFormListener {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
//Inflate the layout using LayoutInflater
layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
floatingLayout = (ConstraintLayout) layoutInflater.inflate(R.layout.service_floating_layout, null);
floatingLay_root = floatingLayout.findViewById(R.id.floatingLay_root);
floatingLay_main = floatingLayout.findViewById(R.id.floatingLay_main);
floatingLay_emptyImg = floatingLayout.findViewById(R.id.floatingLay_emptyImg);
...
//Set layout params to display the controls over any screen.
int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
LAYOUT_FLAG,
0,
PixelFormat.TRANSLUCENT);
// From API26, TYPE_PHONE deprecated. Use TYPE_APPLICATION_OVERLAY for O
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
params.type = WindowManager.LayoutParams.TYPE_PHONE;
//Initial position of the floating controls
params.gravity = Gravity.BOTTOM | Gravity.START;
params.x = 0;
params.y = 0;
//Add the controls view to windowManager
windowManager.addView(floatingLayout, params);
//Task page btn
floatingLay_infoContentNextPage.setOnClickListener(v -> {
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("Title")
.setMessage("Are you sure?")
.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
});
return START_STICKY;
}
How can I show dialog, front of layout ?
You can make an activity without a layout just to show the Alert dialog.
public class MyAlertDialog extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new AlertDialog.Builder(this)
.setTitle("Title")
.setMessage("Message")
...
...
.show()
}
}
Remember to finish the activity.
You can set the title and message dynamically by passing them through intent.
Service
Intent intent = new Intent(this, MyAlertDialog.class);
intent.putExtra("titleKey", "title");
intent.putExtra("messageKey", "messge");
startActivity(intent);
And inside the activity, read it as:
getIntent().getStringExtra("titleKey")
getIntent().getStringExtra("messageKey")

Android Create View Crash

I'm trying to add Layout with this code:
LayoutInflater layoutInflater = (LayoutInflater) activity.getSystemService(LAYOUT_INFLATER_SERVICE);
mYouTubePlayerLayout = (ConstraintLayoutKeyDispatchWrapper) layoutInflater.inflate(R.layout.background_player_layout, null, false);
mYouTubePlayerLayout.setOnDispatchKeyEventListener(this);
mWindowManager = (WindowManager) activity.getSystemService(WINDOW_SERVICE);
createWindowParams(true);
mWindowManager.addView(mYouTubePlayerLayout, mWindowParams);
I understand that I need to get permissions from the user for 23 version and above, so I'm asking the user for the permission with this code:
if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(this)) {
isAppPlayStorePermission = true;
AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
dialog.setCancelable(false);
dialog.setIcon(R.drawable.ic_launcher);
dialog.setTitle(R.string.dialog_need_playstore_permissions_title);
dialog.setMessage(R.string.dialog_need_playstore_permissions_description);
dialog.setPositiveButton(R.string.button_exit, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
AndroidUtils.exitApp(activity);
}
});
dialog.setNegativeButton(R.string.button_settings, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 0);
}
});
dialog.show();
}
but now I'm getting a crash from Fabric:
Fatal Exception: java.lang.RuntimeException
Unable to create service ***: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W#c7450fc -- permission denied for this window type
The crash is only for users with Android OS of 7 and below.
Any idea what is the problem?

app crashes when create alertDialog with a null context

I'm a new android developer, suffering from a problem recently.
The background is that i need to show an AlertDialog when a back-end asyncTask finished. However the activity may be GC'd after a long time asyncTask, so that the context tobe input param of AlertDialog is null.Is there any workaround to solve this problem.
I use this function to show dialog:
public static Dialog showDialog(
Context ctx, int themeId, String title, String message,
int okStrId, android.content.DialogInterface.OnClickListener okListener,
int cancelStrId, android.content.DialogInterface.OnClickListener cancelListener) {
if (ctx != null) {
AlertDialog.Builder builder;
if (themeId > 0)
builder = new AlertDialog.Builder(new ContextThemeWrapper(ctx, themeId));
else
builder = new AlertDialog.Builder(ctx);
if (title != null)
builder.setTitle(title);
builder.setMessage(message);
builder.setPositiveButton(ctx.getString((okStrId < 0) ? R.string.ok : okStrId),
(okListener != null) ? okListener : sDefaultDialogListener);
if (cancelListener != null)
builder.setNegativeButton(ctx.getString((cancelStrId < 0) ? R.string.cancel : cancelStrId), cancelListener);
else {
builder.setCancelable(false);
}
AlertDialog ad = builder.create();
ad.show();
return ad;
}else {
Context context = SuccessFactorsApp.getAppContext();
DialogActivity.launchActivity(ctx,themeId,title,message,okStrId,okListener,cancelStrId,cancelListener);
return new AlertDialog.Builder(context).create();
}
}
I tried to use an Activity to simulate the dialog but not sure how to deal with the DialogInterface.OnClickListener.
Add this to your code:
if(!((Activity) context).isFinishing())
{
//show dialog
}
While running asyntask and doing background activity gets killed and Garbage collected..Hence on completion of task you cannot show a dialog without activity.You can try either
1.By adding below permission showing your dialog .Add this permission to manifest
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
And while showing dialog add this line of code before dialog.show()
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
2.On finsihing of the task launch the wanted activity and open application
3.Use Toast instead of dialog.

User select image from gallery or from custom Camera and not Camera app for image

I would like the user to be able to click on a button and have the option of selecting the gallery or similar apps or a camera activity I have in my app not the build-in one . I read the related answers here and here . However, I don't want to include the build-in camera app, but I want to include my Camera Activity.
I have the following set up so far, taken from the two links I posted:
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
Intent gallIntent = new Intent(Intent.ACTION_GET_CONTENT);
gallIntent.setType("image/*");
Intent camIntent = new Intent(UserEventsActivity.this,CameraActivity.class);
camIntent.setComponent(new ComponentName("MCamera", "Camera"));
List<Intent> yourIntentsList = new ArrayList<Intent>();
yourIntentsList.add(camIntent);
List<ResolveInfo> listGall = getApplicationContext().getPackageManager().queryIntentActivities(gallIntent, 0);
for (ResolveInfo res : listGall) {
final Intent finalIntent = new Intent(gallIntent);
finalIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
yourIntentsList.add(finalIntent);
}
pickIntent.putExtra(Intent.EXTRA_INTENT, yourIntentsList.toArray(new Parcelable[]{}));
pickIntent.putExtra(Intent.EXTRA_TITLE, "Select Source");
startActivityForResult(pickIntent, 1);
What results from this, is a large list of unrelated apps and services, most of which are actually repeated several times in the list. In addition, my camera activity is not among them. When I just do pickIntent.putExtra(Intent.EXTRA_INTENT,gallIntent) I do get the related gallery apps I want, but I can't add my activity.
Any ideas as to what I am doing wrong?
In addition, no service opens when I click on it. However, this may be related to the '1' arg in startActivityOnResult as I'm not exactly sure what to put for that arg.
I came up with a possible solution, that seemed to work for me. I used a custom Dialog:
final Dialog choosePicContent = new Dialog(UserEventsActivity.this);
ScrollView scrollContent = new ScrollView(UserEventsActivity.this);
choosePicContent.addContentView(scrollContent, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
LinearLayout scrollLayout = new LinearLayout(UserEventsActivity.this);
scrollContent.addView(scrollLayout);
scrollLayout.setOrientation(LinearLayout.VERTICAL);
TextView title = new TextView(UserEventsActivity.this);
title.setText(R.string.selectsource);
scrollLayout.addView(title);
Intent gallIntent = new Intent(Intent.ACTION_GET_CONTENT);
gallIntent.setType("image/*");
final Intent camIntent = new Intent(UserEventsActivity.this,CameraActivity.class);
ImageButton camButton = new ImageButton(UserEventsActivity.this);
camButton.setImageDrawable(getApplicationContext().getDrawable(R.drawable.ic_menu_camera));
camButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
camIntent.putExtra("User",current_user);
startActivity(camIntent);
}
});
scrollLayout.addView(camButton);
List<ResolveInfo> listGall = getApplicationContext().getPackageManager().queryIntentActivities(gallIntent, 0);
for (ResolveInfo res : listGall) {
final Intent finalIntent = new Intent(gallIntent);
finalIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
ImageButton iconButton = new ImageButton(UserEventsActivity.this);
iconButton.setImageDrawable(res.activityInfo.loadIcon(getPackageManager()));
iconButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivityForResult(finalIntent,1);
}
});
scrollLayout.addView(iconButton);
}
choosePicContent.show();

How to crop image in java for android with OS Lollipop

I have the following code for cropping images. It's working perfectly in android version 4 or OS Kitkat, but its not working on Android version 5 or OS Lollipop.
I've already searched the whole world but couldn't find the answer...
Here's my code:
In OS Kitkat: this list variable return a value. but,
In OS Lollipop: this list variable return a empty arraylist.
final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = getPackageManager().queryIntentActivities( intent, 0 );
PackageManager test = getPackageManager();
int size = list.size();
if (size == 0) {
Toast.makeText(this, "Can not find image crop app", Toast.LENGTH_SHORT).show();
return;
} else {
intent.setData(mCapturedImageURI);
intent.putExtra("outputX", 110);
intent.putExtra("outputY", 110);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
if (size == 1) {
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, CROP_FROM_CAMERA);
} else {
for (ResolveInfo res : list) {
final CropOption co = new CropOption();
co.title = getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
co.icon = getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
co.appIntent= new Intent(intent);
co.appIntent.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
cropOptions.add(co);
}
CropOptionAdapter adapter = new CropOptionAdapter(getApplicationContext(), cropOptions);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose Crop App");
builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dialog, int item ) {
startActivityForResult( cropOptions.get(item).appIntent, CROP_FROM_CAMERA);
}
});
builder.setOnCancelListener( new DialogInterface.OnCancelListener() {
#Override
public void onCancel( DialogInterface dialog ) {
if (mCapturedImageURI != null ) {
getContentResolver().delete(mCapturedImageURI, null, null );
mCapturedImageURI = null;
}
}
} );
AlertDialog alert = builder.create();
alert.show();
}
}
I had already given android.permission.MANAGE_DOCUMENTS permission. But facing the same issue. After searching a lot, i found the solution.
Here's a workaround, for the time being:
Intent mIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(mIntent, CHOOSE_IMAGE);
This forces the older image gallery to open instead of the new Kitkat documents view.
Now, you can get the Uri by calling the following in your onActivityResult:
Uri selectedImageURI = data.getData();
Hope this help to solve your problem.

Categories

Resources