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
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")
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?
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.
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();
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.