Get Texture from google play game services Icon Uri in Libgdx - java

I am trying to show user profile icon in my game in libgdx. In the android side of code, i can get the image uri for the player using mParticipants.get(i).getIconImageUri() which gives me the Uri. But I can't find a way to convert the Uri to Texture which i can consume in my libgdx code.
I tried first getting the bitmap from Uri using the code
Bitmap bitmap = null;
try {
InputStream inputStream = application.getContentResolver().openInputStream(imgUri);
bitmap = BitmapFactory.decodeStream(inputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
But this gives me a security error.
Other answers on google shows me the ways, all of which include the ways to show image in an Android ImageView but i need a texture which i can use in my libgdx game to show the image
I have also tried adding following permission to my manifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Even then i am still getting security error. Please help me to resolve this issue

After a lot of research it seemed to me that it is Not Possible to get the bitmap by reading the input stream for the Uri. The only way to do this is using the ImageManager
The sample code for achieving this is:
private void SetUserIconForPlayer(final Player player, Uri uri)
{
ImageManager mgr = ImageManager.create(application);
mgr.loadImage(new ImageManager.OnImageLoadedListener() {
#Override
public void onImageLoaded(Uri uri,final Drawable drawable, boolean isRequestedDrawable) {
if(isRequestedDrawable)
{
Gdx.app.postRunnable(new Runnable() {
#Override
public void run() {
player.SetUserIcon(GetTextureFromDrawable(drawable));
}
});
}
}
}, uri);
}

Related

Drawable.createFromPath(path) returns null, imgView.setImageURI returns null, image added manually and called programmatically

Im trying to do the next:
Find image from device and add it to programm (done!)
Store image URI to string and save it to .txt file (done!)
Extract URI from .txt file (done!)
Open a dialog window to show the image on click - and there is a problem - i've tryied everything i found on google and stack overflow - both methods does not work - drawable returns no image (drawable = null), and setImageURI crashes the application.
Debugger shows something like that:
content://com.android.providers.media.documents/document/image%3A31
code:
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.pop_up_add_item, null);
final Button btn=view.findViewById(R.id.test);
imgg=view.findViewById(R.id.img);
String str_tooltip=getArguments().getString("Entity");
String main_str=getArguments().getString("Original");
String str_adress=getArguments().getString("Uri");
Uri uri = Uri.parse(str_adress);
//imgg.setI(uri);
if (str_adress!=null & str_adress.length()>0) {
final Uri uri1 = Uri.parse(str_adress);
//final String path = uri.getPath();
//File drawableFile = new File(getApplicationContext().getFilesDir().getAbsolutePath()+"/into11.png");
//final Drawable drawable = Drawable.createFromPath(path);
imgg.setImageURI(uri);
}
Is there any solution on this? Probably common problem?
UPDATE
After tried all the available options eventually (thanks to sir #Dilshad) i've found that the trouble is caused by java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{1a24ed9 11931:com.example.myapplication/u0a121} (pid=11931, uid=10121) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs --> Permission issue.
So, trying to solve it i added:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage"/>
in AndroidManifest
and
int result = ContextCompat.checkSelfPermission(takeThis, android.Manifest.permission.READ_EXTERNAL_STORAGE);
in the place in the code where the access begins.
But till the moment problem is not solved.

Android - Download Unsuccessful and Parsing Error while trying to download and install .apk from server

The goal is to update my app without using the google play store. I’m trying to download a .apk file from a server and then install it programmatically. I’m currently getting an error that the download is unsuccessful and that there was an error while parsing the package. I have the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions requested at runtime. I had to go into the tablet's settings to give permission to “Install unknown apps”. I cannot get REQUEST_INSTALL_PACKAGES to be requested at runtime.
If I change the fileName and update URL to get a .txt that I store in the same folder on the server as the .apk AND comment out “.setMimeType()” I can download and view a .txt file.
Have the updates to Android Studio made older tutorials or examples of this outdated?
Is there a new or better way to download .apk’s from servers programmatically?
Is the lack of REQUEST_INSTALL_PACKAGES permission at runtime what is preventing my .apk from downloading?
Any advice on how to fix my code?
Here are some code snippets to help
gradle:app
android {
compileSdk 31
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "farrpro.project"
minSdk 28
targetSdk 30
}
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.ACTION_INSTALL_PACKAGE"/>
MainActivity.java
private void hasInstallPermission() { // runs in onCreate()
if (getApplicationContext().checkSelfPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 1);
}
}
void downloadAndInstallUpdate(){ // runs when users accepts request to download update
String fileName = "update.apk";
// example of update’s string
update = “https://myserver.net/update.apk”;
//set download manager
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(update));
request.setTitle(fileName)
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setDescription("Downloading")
//.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
.setMimeType("application/vnd.android.package-archive");
// get download service and enqueue file
final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
final long downloadId = manager.enqueue(request);
System.out.println("Max Bytes: "+DownloadManager.getMaxBytesOverMobile(this)); //returns null
//set BroadcastReceiver to install app when .apk is downloaded
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
System.out.println("Is download successful: "+ manager.getUriForDownloadedFile(downloadId)); //returns null
System.out.println("Mime: "+manager.getMimeTypeForDownloadedFile(downloadId)); //returns application/vnd.android.package-archive
Intent install = new Intent(Intent.ACTION_VIEW);
File file = new File(ctxt.getExternalFilesDir(null) + fileName);
Uri downloadedApk = FileProvider.getUriForFile(ctxt, "farrpro.project.provider", file);
install.setDataAndType(downloadedApk,
manager.getMimeTypeForDownloadedFile(downloadId));
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
startActivity(install);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Log.e("TAG", "Error in opening the file!");// this never prints
}
unregisterReceiver(this);
finish();
}
};
//register receiver for when .apk download is complete
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
The problem was the server had restricted download types. My code worked more or less after that setting was changed. I ended up needing to change the intents in my broadcast receiver so that after the download was completed the new .apk would immediately install. Here are the changes I made to make the code posted work.
final long downloadId = manager.enqueue(request);
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent1) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(manager.getUriForDownloadedFile(downloadId), "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
getApplicationContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Log.e("TAG", "Error in opening the file!");
}
unregisterReceiver(this);
finish();
}
};
If your app is running on Android O or newer, you have to allow unknown app sources for your app.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!context.packageManager.canRequestPackageInstalls()) {
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).apply {
data = Uri.parse(String.format("package:%s", context.packageName))
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(intent)
}
}

saving a captured image to external storage failed

I want to save my captured images to a specific directory (/sdcard/DCIM/FokusStacker) with the following method. I have tried different Locations, but none of them worked.
private void capturePicture(){
File dir = new File("/sdcard/DCIM/FokusStacker");
String fileName = "IMG_"+ System.currentTimeMillis();
File file = new File(dir,fileName);
Log.d(TAG, "capturePicture: DIRECTORY: "+dir.getAbsolutePath());
ImageCapture.OutputFileOptions outputFileOptions =
new ImageCapture.OutputFileOptions.Builder(file).build();
imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(this), new ImageCapture.OnImageSavedCallback() {
#Override
public void onImageSaved(#NonNull ImageCapture.OutputFileResults outputFileResults) {
Log.d(TAG, "onImageSaved: SAVED");
return;
}
#Override
public void onError(#NonNull ImageCaptureException exception) {
Log.d(TAG, "onError: FAILED");
return;
}
});
}
These are the Permission i've included:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
And i also tried saving it to the internal storage.
Code Snippet for to get the local directoryof the App for the file:
File dir = getApplicationContext().getFilesDir();
Can anyone please guide me how to do this?
I am a little new to android so please, I would appreciate if I can have a detailed procedure.

Is it possible to programmatically take photo with native Camera app on Android device without physically tapping the capture button?

Just as the title say, is it possible to programmatically interact/configure with native Camera app on Android device?
For example, I am trying to have the native camera app to take a picture without having to physically touch the capture button. I'm not wanting to use internal-timer feature in the camera app since this requires physical touch to the button as well.
So simply put, I want to know if it is possible to take a picture without physically touching the capture button.
Thanks in advance for the reply.
is it possible to programmatically interact/configure with native Camera app on Android device?
Not from an ordinary Android app.
Also, please note that there are several thousand Android device models. There are hundreds of different "native Camera app" implementations across those device models, as device manufacturers often implement their own. Your question implies that you think that there is a single "native Camera app", which is not the case.
For an individual device model, or perhaps a closely related family of devices, with a rooted device, you might be able to work something out with simulated user input. However, the myriad of camera apps means that you would need different rules for each app.
Also, if you are only concerned about your own device, you can use the uiautomator test system to control third-party apps, but that requires a connection to your development machine, as the tests are run from there.
It is possible. Just forget about "native Camera app" and use Camera/Camera2 API directly.
Some time ago I tried to make a background service taking pictire periodically, detects face and measure eyes distance to prevent my little dougter watching tab too close, but this was fail because tab camera angle was too narrow to take all her face.
I posted part of this app here (this code use depricated Camera interface. It was replaced by Camera2 interface since API21):
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
surfaceTexture = new SurfaceTexture(0);
}
public void takePictire() {
Camera cam = openFrontCamera(mContext);
if (cam != null) {
try {
cam.setPreviewTexture(surfaceTexture);
cam.startPreview();
cam.takePicture(null, null, mPicture);
} catch (Exception ex) {
Log.d(LOG_TAG, "Can't take picture!");
}
}
}
private static Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(data), null, bfo);
// Eye distance detection here and saving data
camera.stopPreview();
camera.release();
}
};
/* Check if this device has a camera */
private static Camera openFrontCamera(Context context) {
try {
boolean hasCamera = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
if (hasCamera) {
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
try {
cam = Camera.open(camIdx);
} catch (RuntimeException e) {
Log.e(LOG_TAG, "Camera failed to open: " + e.getLocalizedMessage());
}
}
}
return cam;
}
} catch (Exception ex) {
Log.d(LOG_TAG, "Can't open front camera");
}
return null;
}
Some additional info. To use this code you app should have camera permission in AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
Yes, You can capture image without any user input also in background without frame. Take a look here . Hope this help you!

upload photo to Facebook from Android

I'm trying to upload photo to Facebook from my Android App and it works fine, photo is uploaded, problem is, Facebook app doesn't open, my App simply uploads photo directly to News Feed, but without option to maybe discard it, or change text or antything, so what i would like is to open facebook post with my image attached but not posted until i click the "post"
here is my code :
Bitmap img = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
Request uploadRequest = Request.newUploadPhotoRequest(
Session.getActiveSession(), img, new Request.Callback() {
#Override
public void onCompleted(Response response) {
Toast.makeText(MyActivity.this,
"Photo uploaded successfully",
Toast.LENGTH_LONG).show();
}
});
uploadRequest.executeAsync();
I googled around for hours, and this facebook sdk is messed up, i can't seem to find any proper answer, if i use shareDialog facebook provides, i can't share local images, if i dont use share dialog i can't open facebook app, and i don't want to use OpenGraph stories .. Any help would be gravely appreciated.
You can post imade or text into facebook by using facebook SDK wich is explaned here
and to post an image
private void postImageToWall(String accessToken,byte[] image, String text){
Bundle params = new Bundle();
params.putString(Facebook.TOKEN, accessToken);
//text with the image
params.putString("message",text);
// The byte array is the data of a picture.
params.putByteArray("picture", image);
try {
facebook.request("me/photos", params, "POST");
uploadSucceed = true;
} catch (FileNotFoundException fileNotFoundException) {
showToast(fileNotFoundException.getMessage());
} catch (MalformedURLException malformedURLException) {
showToast(malformedURLException.getMessage());
} catch (IOException ioException) {
showToast(ioException.getMessage());
}
}

Categories

Resources