I am trying to make the "Take photo" tutorial from here and after following all the steps I still have an error. More exactly after I take the picture it displays the message "camera has stopped". I added a button that opens the camera on click and an imageView to display the photo. I am trying to deploy the app on Samsung Galaxy S7 (Android 8.0.0,API 26).
This is the setOnClickListener:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById((R.id.button));
ImageView imageView = (ImageView)findViewById(R.id.imageView);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
button.setEnabled(false);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
}
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dispatchTakePictureIntent();
}
});
}
And this is the methos for camera:
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File imageView = null;
try {
imageView = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
ex.printStackTrace();
}
// Continue only if the File was successfully created
if (imageView != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.camapp.fileprovider",
imageView);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
The file path:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="my_images"
path="Android/data/com.example.camapp/files/Pictures" />
</paths>
And the permission:
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Provider:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.camapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
And i have the same method for onActivityResult() createImageFile() and galleryAddPic() from the tutorial.
Here is the stacktrace:
java.lang.IllegalStateException: #NotNull method com/android/tools/idea/gradle/project/model/AndroidModuleModel.getRootDir must not return null
at com.android.tools.idea.gradle.project.model.AndroidModuleModel.$$$reportNull$$$0(AndroidModuleModel.java)
at com.android.tools.idea.gradle.project.model.AndroidModuleModel.getRootDir(AndroidModuleModel.java:571)
at com.android.tools.idea.gradle.project.sync.setup.module.android.ContentRootsModuleSetupStep.findContentEntries(ContentRootsModuleSetupStep.java:71)
at com.android.tools.idea.gradle.project.sync.setup.module.android.ContentRootsModuleSetupStep.doSetUpModule(ContentRootsModuleSetupStep.java:58)
at com.android.tools.idea.gradle.project.sync.setup.module.android.ContentRootsModuleSetupStep.doSetUpModule(ContentRootsModuleSetupStep.java:41)
at com.android.tools.idea.gradle.project.sync.setup.module.ModuleSetupStep.setUpModule(ModuleSetupStep.java:35)
at com.android.tools.idea.gradle.project.sync.setup.module.common.BaseSetup.setUpModule(BaseSetup.java:41)
at com.android.tools.idea.gradle.project.sync.ng.ModuleSetup.setupModuleModels(ModuleSetup.java:141)
at com.android.tools.idea.gradle.project.sync.ng.CachedProjectModelsSetup.setUpModules(CachedProjectModelsSetup.java:116)
at com.android.tools.idea.gradle.project.sync.ng.ProjectSetup$ProjectSetupImpl.setUpProject(ProjectSetup.java:82)
at com.android.tools.idea.gradle.project.sync.ng.SyncResultHandler.onSyncSkipped(SyncResultHandler.java:164)
at com.android.tools.idea.gradle.project.sync.ng.NewGradleSync.trySyncWithCachedGradleModels(NewGradleSync.java:219)
at com.android.tools.idea.gradle.project.sync.ng.NewGradleSync.sync(NewGradleSync.java:165)
at com.android.tools.idea.gradle.project.sync.ng.NewGradleSync.access$000(NewGradleSync.java:59)
at com.android.tools.idea.gradle.project.sync.ng.NewGradleSync$2.run(NewGradleSync.java:151)
at com.intellij.openapi.progress.impl.CoreProgressManager$TaskRunnable.run(CoreProgressManager.java:736)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$1(CoreProgressManager.java:157)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:580)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:525)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:85)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:144)
at com.intellij.openapi.progress.impl.CoreProgressManager$4.run(CoreProgressManager.java:395)
at com.intellij.openapi.application.impl.ApplicationImpl$1.run(ApplicationImpl.java:314)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
I want to make a button that opens the camera take a picture and save it in the gallery or other specified directory because I will make some image processing on that photo.I tried almost all the tutorials on yt and I really had a hard time finding a solution for this problem.I appreciate any solution or suggestion you have.Thank you for you're time!
If your app requires the camera to click a picture, the CAMERA permission should be asked
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<uses-permission android:name="android.permission.CAMERA"/>
<!-- other permissions go here -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application ...>
...
</application>
Your app should then prompt user to grant the camera & storage permissions
if (ContextCompat.checkSelfPermission(YourActivityName.this,
Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},
YOUR_PERMISSIONS_REQUEST_CODE);
// YOUR_PERMISSIONS_REQUEST_CODE is an
// app-defined int constant. The callback method gets the
// result of the request.
} else {
// Permission has already been granted
}
Also define the file provider in manifest file
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.yourPackageName.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_list"></meta-data>
</provider>
Related
I'm trying to use usb camera devices connected to my android device. So initially i have got the details of the usb devices connected through UsbManager.getDeviceList() method. Then i iterated through every device and requested for permission if permission was already not granted.
Prior to requesting the permission i have registered a global BroadCastReceiver to listen to the response of the requested permission.
Here is the MainActivity.java:
public class MainActivity extends AppCompatActivity {
private UsbManager usbManager_;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
public PendingIntent permissionIntent;
private static String TAG = "testing";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// SurroundView surroundView = new SurroundView(this);
// setContentView(surroundView);
usbManager_ = (UsbManager) getSystemService(USB_SERVICE);
permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
requestUsbPermissions();
}
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i(TAG, "received intent by broadcast " + intent.getAction());
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
Log.i(TAG, "got the permission");
}
} else {
Log.d(TAG, "permission denied for device " + device);
}
}
}
}
};
public void requestUsbPermissions(){
HashMap<String, UsbDevice> deviceList = usbManager_.getDeviceList();
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
this.registerReceiver(usbReceiver, filter);
Log.i(TAG, "registered broadcast receiver!");
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while (deviceIterator.hasNext()) {
UsbDevice device = deviceIterator.next();
Log.i(TAG,
"Camera: device Id " + device.getDeviceId() + " device mName : " + device.getDeviceName());
if (!usbManager_.hasPermission(device)) {
Log.i(TAG, "requesting permission");
usbManager_.requestPermission(device, permissionIntent);
}
}
}
}
So when i run the app it detects one usb device connected and requests permission for the same. But the dialog box which asks for user input never comes. Instead when the intent is received by the BroadCastReceiver the value of intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false) will always be false which means the permission is already denied. Can anyone explain to me why the dialog box is not coming in the first place and why the permission is denied automatically.
Here is my AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.vision_sdk_testing">
<uses-feature android:name="android.hardware.usb.host" android:required="true"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
And below is the output log:
2020-05-01 17:56:05.282 30769-30769/com.example.vision_sdk_testing I/testing: registered broadcast receiver!
2020-05-01 17:56:05.283 30769-30769/com.example.vision_sdk_testing I/testing: Camera: device Id 1003 device mName : /dev/bus/usb/001/003
2020-05-01 17:56:05.283 30769-30769/com.example.vision_sdk_testing I/testing: requesting permission
2020-05-01 17:56:05.301 30769-30769/com.example.vision_sdk_testing I/testing: received intent by broadcast com.android.example.USB_PERMISSION
2020-05-01 17:56:05.302 30769-30769/com.example.vision_sdk_testing D/testing: permission denied for device UsbDevice[mName=/dev/bus/usb/001/003,mVendorId=1443,mProductId=38192,mClass=239,mSubclass=2,mProtocol=1,mManufacturerName=Sonix Technology Co., Ltd.,mProductName=USB 2.0 Camera,mVersion=1.00,mSerialNumberReader=android.hardware.usb.IUsbSerialReader$Stub$Proxy#d41ebfa,mConfigurations=[
UsbConfiguration[mId=1,mName=null,mAttributes=128,mMaxPower=128,mInterfaces=[
UsbInterface[mId=0,mAlternateSetting=0,mName=HD USB Camera,mClass=14,mSubclass=1,mProtocol=0,mEndpoints=[]]
UsbConfiguration[mId=3,mName=null,mAttributes=3,mMaxPower=88,mInterfaces=[]]
Any help is appreciated. Thanks!
For me, I had to go into the app's permissions in the settings menu and give my app the Camera permission. I'm guessing it's because my USB device is a camera? Once I granted this permission, the app worked just as described in the docs https://developer.android.com/guide/topics/connectivity/usb/host
EDIT: Facebook issue : https://developers.facebook.com/support/bugs/2434932356771915/
I'm trying to share a bitmap to an Instagram story sticker.
But it loads Instagram, but doesn't show any sticker, no background colors, only a black story screen.
What is wrong with this code ? I check if file was in the external data cache directory and that's good.
According to Facebook's Instagram documentation :
I added read/write rights to storage and a provider to my AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<provider
android:authorities="my.app.id.fileprovider"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
I added a file_paths.xml to share my external cache folder to other apps
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-cache-path name="share" path="."/>
</paths>
</resources>
I create a bitmap from a drawable, write it to a file on the external cache dir, and apply the Intent like example in the docs
public static void sendStickerToInstagram() {
Bitmap bm = BitmapFactory.decodeResource(context.getResources(), R.drawable.sticker);
File extStorageDirectory = context.getExternalCacheDir();
File stickerFile = new File(extStorageDirectory, "sticker.png");
try {
FileOutputStream outStream = new FileOutputStream(stickerFile);
bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
} catch (IOException e) {
Log.e("TEST", e.getMessage());
}
Uri stickerUri = FileProvider.getUriForFile(activity, "my.app.id.fileprovider", stickerFile);
// Uri stickerUri = Uri.fromFile(stickerFile);
String linkUrl = "https://stackoverflow.com";
Intent intent = new Intent("com.instagram.share.ADD_TO_STORY");
intent.setType("image/*");
intent.putExtra("interactive_asset_uri", stickerUri);
intent.putExtra("content_url", linkUrl);
intent.putExtra("top_background_color", "#33FF33");
intent.putExtra("bottom_background_color", "#FF00FF");
grantUriPermission("com.instagram.android", stickerUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (getPackageManager().resolveActivity(intent, 0) != null) {
startActivityForResult(intent, 0);
}
}
Most strange part is when I test to share my sticker as background, it works, so the file is loaded as espected, with all permissions.
Intent intent = new Intent("com.instagram.share.ADD_TO_STORY");
intent.setDataAndType(stickerUri, "image/*");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra("content_url", linkUrl);
if (activity.getPackageManager().resolveActivity(intent, 0) != null) {
activity.startActivityForResult(intent, 0);
}
Any idea why I can't share a sticker ?
Don't worry... It's not you. It's Instagram. :P
Their most recent release of Instagram on Android broke the
com.instagram.share.ADD_TO_STORY intent.
Keep an eye on this thread for updates.
https://developers.facebook.com/support/bugs/2434932356771915/
I'm having some trouble with Intent Action_Call. I put the permission in Manifest, but it doesn't work. I press the button to Call and nothing happens. The app that I'm making is an app that does multiple Intents so the code isn't in MainActivity. I don't know if it helps, but I'm using API 28.
Thanks for reading.
MANIFEST:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.intentsimplicitas">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".SmsActivity"></activity>
<activity android:name=".DialActivity" />
<activity android:name=".WaysActivity" />
<activity android:name=".MapActivity" />
<activity android:name=".PageActivity" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
JAVA (DialActivity.java)
public class DialActivity extends Activity {
Button btnDial;
EditText edtPhone;
String phone;
Intent it;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dial);
btnDial = (Button)findViewById(R.id.btnDial);
edtPhone = (EditText)findViewById(R.id.edtPhone);
}
public void dialClick (View v) {
phone = edtPhone.getText().toString();
Uri uri = Uri.parse("tel: " + phone);
it = new Intent(Intent.ACTION_CALL);
it.setData(uri);
startActivity(it);
}
}
From https://developer.android.com/training/permissions/requesting:
Requesting permission:
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.CALL_PHONE)) {
// 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.CALL_PHONE},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
// MY_PERMISSIONS_REQUEST_CALL_PHONE is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
// Permission has already been granted
}
Verifying:
#Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_CALL_PHONE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
You can do via Intent
public void dialClick (View v) {
phone = edtPhone.getText().toString();
Uri uri = Uri.parse("tel: " + phone);
it = new Intent(Intent.ACTION_DIAL);
it.setData(uri);
startActivity(it);
}
You need to add the permissions at run time to be able to make the call, I recommend the following library, since it is much easier to implement the permissions in time of execution.
https://github.com/Karumi/Dexter
I am trying to make a simple application in Java to install an APK on Android devices connected via USB. Using ABD manually or installing from Android Studio it works fine, but I wanted to give a simple single button click install option within my application, I have tried following code but unfortunately, it is not working
abdsourcesync = apkpath;
progress.setString("sync in progress");
System.out.println("Starting Sync via adb with command " + "adb"
+ " install -r " + apkpath);
Process process = Runtime.getRuntime().exec(
"adb" + " install -r " + apkpath);
InputStreamReader reader = new InputStreamReader(
process.getInputStream());
Scanner scanner = new Scanner(reader);
scanner.close();
int exitCode = process.waitFor();
System.out.println("Process returned: " + exitCode);
I have searched around here but I have only found installing an APK from within an Android application or from the android studio, not from a core Java. or java web module
Your helping hand would be really appreciated ;
Do not forget about runtime permissions
This simple example works for me for API 28.
It opens an apk file to install from "Download folder"
For simplification:
Download the apk file for application you want to install to "Download" folder of your phone. (There are a lot of instructions to do it programmaticaly, ot you can do it manualy)
TO DO
Create new project
Add a button to MainActivity
Create xml folder in res folder and create a file_paths.xml file there
Use the code bellow
Enjoy =)
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.teko.testcleanopenfile">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
</application>
</manifest>
MainActivity
public class MainActivity extends AppCompatActivity {
TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// textView and button
textView = findViewById(R.id.textView);textView.setText("Hello updatable World\n");
(findViewById(R.id.button)).setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(View view) {RunAPK(getBaseContext());}
});
}
private void RunAPK(Context context){
requestPermissionsToRead();
}
private void requestPermissionsToRead() {
// ASK RUNTIME PERMISSIONS
ActivityCompat.requestPermissions(MainActivity.this, new String[]{READ_EXTERNAL_STORAGE},111);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (grantResults.length > 0) {
if (requestCode == 111 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
textView.append("Permission granted write\n");
// Create Uri
File downloads = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File file1 = new File (downloads + "//app-debug.apk");//downloads.listFiles()[0];
Uri contentUri1 = getUriForFile(this, BuildConfig.APPLICATION_ID, file1);
// Intent to open apk
Intent intent = new Intent(Intent.ACTION_VIEW, contentUri1);
intent.setDataAndType(contentUri1, "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
}
}
}
}
file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="download" path="."/>
</paths>
You can Install Application from Java code using below way.
File outputFile = null;
try {
outputFile = new File(<APK Path>);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri apkUri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".provider", outputFile);
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(apkUri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
mContext.startActivity(intent);
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N){
Uri apkUri = Uri.fromFile(outputFile);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}else {
Toast.makeText(mContext, "File not found.", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
I'm trying to create a system overlay. But I keep getting "permission denied". I'm using SDK version 23.
My manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test" >
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".activity.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>
</manifest>
The code I use to create the overlay:
//mView = new HUDView(this);
mButton = new Button(this);
mButton.setText("Overlay button");
mButton.setOnTouchListener(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.RIGHT | Gravity.TOP;
params.setTitle("Load Average");
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mButton, params);
First, there is no permission named SYSTEM_OVERLAY_WINDOW. It is SYSTEM_ALERT_WINDOW.
Second, if your targetSdkVersion is 23 or higher, and you are running on Android 6.0+ devices, your app will not get this permission at the outset. Call Settings.canDrawOverlays() to see if you have the permission, and use ACTION_MANAGE_OVERLAY_PERMISSION to lead the user over to Settings if you do not.
In AndroidManifest (for version < 23)
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE= 5469;
//Random value
public void testPermission() {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}
}
Result :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (Settings.canDrawOverlays(this)) {
// You have permission
}
}
}
You can also lead the user over to the specific app's overlaying page. The documentation states:
Input: Optionally, the Intent's data URI can specify the application package name to directly invoke the management GUI specific to the package name. For example "package:com.my.app".
So something like:
intent.setData(Uri.fromParts("package", getPackageName(), null));
As an alternative solution, you can try WindowManager.LayoutParams.TYPE_TOAST instead of WindowManager.LayoutParams.TYPE_SYSTEM_ALERT.
This not requires any permission.
I'm using it to show image, maybe button will work to
for users below and above android 8 use
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}
I handled all of the overlay permissions for every android version in my library. Please see the gist here.
For Display over the other apps permissions is required to add in the manifest is
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
To check your app has permission
Settings.canDrawOverlays(context)
To check permission checkOverlayPermission
private const val CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084
private fun checkOverlayPermission(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
//If the draw over permission is not available open the settings screen
//to grant the permission.
val intent = Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:$packageName")
)
startActivityForResult(
intent,
CODE_DRAW_OVER_OTHER_APP_PERMISSION
)
}
}
And in onActivityResult you can check permission is granted or not
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
if (requestCode == CODE_DRAW_OVER_OTHER_APP_PERMISSION) {
if (Settings.canDrawOverlays(this)) {
// Permission Granted
} else {
// Permission not Granted
// If you want then call again checkOverlayPermission until permission granted
}
}
}