Nearby Connections: Why is the payload file from the Downloads folder null? - java

I'm following the File transfer example on the Nearby Connections Exchange page (the "more complex example" code snippet).
I can send an image and receive it on another device in the Download/Nearby folder. The image is sent successfully since if I were to change the file name to give it an appropriate extension (e.g. .jpg), I can open the image in a photo gallery app.
private void processFilePayload(long payloadId) {
Payload filePayload = completedFilePayloads.get(payloadId);
String filename = filePayloadFilenames.get(payloadId);
if (filePayload != null && filename != null) {
completedFilePayloads.remove(payloadId);
filePayloadFilenames.remove(payloadId);
// Retrieve received file from Downloads folder
Payload.File payloadFile2 = filePayload.asFile();
File payloadJavaFile = payloadFile2.asJavaFile();
if (payloadJavaFile == null) {
Log.d(TAG, "Payload java file is null in processFilePayload()");
} else {
payloadJavaFile.renameTo(new File(payloadJavaFile.getParentFile(), filename));
}
}
}
Why is the payloadJavaFile variable null? From looking at Payload.class, I know that the result of asJavaFile() is a nullable File and that, from the asJavaFile() method description, calling asJavaFile() in processFilePayload() from within onPayloadReceived() (as is done in the example on the API page) may lead to the File not having received all of the payload's contents yet. However, I also call processFilePayload() from within onPayloadTransferUpdate() after verifying the success of the PayloadTransferUpdate, and so shouldn't the payload have received all of its contents by this stage (and not be null when calling asJavaFile() on the payload object)?
My code is almost the same as the documentation for both sending and receiving the image and file name.

Payload.asJavaFile() will be null if the READ_EXTERNAL_STORAGE permission is not properly set up for your application. You need READ_EXTERNAL_STORAGE in the AndroidManifest.xml and you need to also request READ_EXTERNAL_STORAGE permission at runtime since it is a dangerous permission. (https://developer.android.com/training/permissions/requesting)
To share files using Nearby Connections, your application will need all of the following:
AndroidManifest.xml
<!-- Required for Nearby Connections -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Optional: needed to share files -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
MainActivity.java
ActivityCompat.requestPermissions(thisActivity,
new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.READ_EXTERNAL_STORAGE
},
PERMISSIONS_REQUEST_CODE);
We will improve the documentation to make this requirement for sharing files more obvious.

I checked the source code. From what I can see, asJavaFile() is always set (and I'm not sure why it's marked as #Nullable).
Unfortunately, for me to look into it any further, I'd need you to provide me with a sample app that reproduces the bug you're seeing.

Related

Android API 23 java.net.UnknownHostException: Unable to resolve host "URL": No address associated with hostname

Im facing a big problem, Im trying to connect to an URL using a GET method. It give me an error java.net.UnknownHostException: Unable to resolve host "URL": No address associated with hostname.
I have been reading some post and all people say it is about permissions.My permissions are:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
I can access to that URL by using chrome in my mobile, it means that wifi is working.
I am using a Motorola g 2, API 23.
Printing the response on the Log ?
Did you try switching of the WiFi or phone or both and tried again ?
This problem can occur when you are on VPN. I had a similar issue. After disconnecting from the VPN I tried connecting again. It got connected.
Also try rechecking the URL since the UnknownHostException is popping up there is high possibility that the URL string you are passing in the program(URL class probably) is wrong.
Hope it helps.
You have two solutions for your problem. The quick one is to lower targetApi to 22 (build.gradle file). Second is to use the new runtimePermission model:
Since your target api is 23 you should add the permissions on runtime too.
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.INTERNET) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(
Manifest.permission.INTERNET)) {
// Explain to the user why we need to read the contacts
}
requestPermissions(new String[]{Manifest.permission.INTERNET},
MY_PERMISSIONS_REQUEST_INTERNET);
// MY_PERMISSIONS_REQUEST_INTERNET is an
// app-defined int constant
return;
}
Sniplet found here: https://developer.android.com/preview/features/runtime-permissions.html

Android READ_EXTERNAL_STORAGE permission not working

I'm trying to create a simple app that can get an image from the Gallery app and display it on an imageButton. I'm testing with API 21 on a phone running Android 5.0.1. Unfortunately, no matter what I try I keep getting a security error - even when I specify the permissions.
My code for getting retrieving the image is:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent){
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode){
case PICK_IMAGE_REQUEST:
if(resultCode == RESULT_OK && imageReturnedIntent != null && imageReturnedIntent.getData() != null) {
Uri uri = imageReturnedIntent.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
// Log.d(TAG, String.valueOf(bitmap));
ImageButton ib = (ImageButton) findViewById(R.id.inputImg);
ib.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
break;
}
}
The code works when I try to select an image from Dropbox, but when I select an image from gallery, I get
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/35634 from pid=25240, uid=10070 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
I made the use-permission tag for READ_EXTERNAL_STORAGE a child of 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="[REDACTED]">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="23" />
<uses-permission tools:node="replace" android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
<application>
[REDACTED]
</application>
</manifest>
I've searched high and low on other posts, but still can't seem to figure out why I'm still getting this pesky error.
PROBLEM
Your have the error
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/35634 from pid=25240, uid=10070 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission().
CAUSE
You are not giving correctly permissions because of android:maxSdkVersion="18", which according to documentation.
The highest API level at which this permission should be granted to your app. Setting this attribute is useful if the permission your app requires is no longer needed beginning at a certain API level.
As long as you didn't give permissions to API 21 your app is behaving ok.
Check this topic for further info.
SOLUTION
If you wanna give read permissions under API 21, you must declare them as:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="21" />
IMPORTANT:
This only make sense when you need to give extra permissions because some old api's require permissions that new versions doesn't, so user experience get's improved because you only ask for certain permissions when needed.
So (in this case) the correct way will be:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
ADD ON
If you want to save data you must add WRITE_EXTERNAL_STORAGE permissions.
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Simply replace with the below one and try,
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
While debugging on some devices you need to grant permission explicitly by going to your settings --> apps --> MY_APPLICATION --> Permissions and then grant required permissions.
In addition to adding the below in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
we also need to request permission in the activity for the app to actually have access to external storage. https://developer.android.com/training/permissions/requesting.html

Picasso Images Will Not Load - Android / Java

I'm attempting to use Picasso to load an ImageView from a URL - however the imageView never seems to populate with the image and I am unsure why.
P.S.
When debugging - the value of 'boxart' is a valid image URL each and every time - so I'm pretty stumped.
Source:
...
Bundle extras = getIntent().getExtras();
if (extras != null) {
String boxart = extras.getString("boxart");
Picasso.with(this).load(boxart).into(imageItem);
...
Also - I'm not getting any errors - it simply does not load the image.
Try installing an error handler and see if that gets called (you set this global listener on your Picasso.Builder:
public class MyClass implements Picasso.Listener {
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
// Display the exception
}
}
Full answer:
https://stackoverflow.com/a/27798536/1715829
Make sure you have the correct permissions:
<uses-permission android:name="android.permission.INTERNET" />
ex.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.alefba.app.cus.eLearning"
android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET" />
<application
...
</application>
</manifest>
Also, make sure your device is connected to a network.
be sure the link is direct

How to retrieve backup of database from app?

I have trying to copy my app database from storage data to any outher floder
but i'm getting some error .
my device is rooted and i have used many apps from google play to nevigate to data/data but it's empty and i have used this code :
public void backup() {
try {
File sdcard = Environment.getRootDirectory();
File outputFile = new File(sdcard,
"YourDatabase.db");
if (!outputFile.exists())
outputFile.createNewFile();
File data = Environment.getDataDirectory();
File inputFile = new File(data,
"data/"+LoginActivity.this.getPackageName()+"/databases/"+"HafilTC.db");
InputStream input = new FileInputStream(inputFile);
OutputStream output = new FileOutputStream(outputFile);
byte[] buffer = new byte[1024];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
output.flush();
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
throw new Error(e.toString());
}
android mainfilfist :
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<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" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
error log :
02-11 18:38:16.213: E/AndroidRuntime(21338): java.lang.Error: java.io.IOException: open failed: EROFS (Read-only file system)
The problem is that Environment.getRootDirectory() does not return the root directory of the SD card. It returns the root OS directory, which you cannot write to.
You should instead use Environment.getExternalStorageDirectory(), which will return the root directory of the user's external storage directory (which may or may not be an SD Card, depending on the device).
You have at least two options here.
Using DDMS
Open Eclipse, and switch to DDMS perspective.
Than follow the path:
DDMS--> file explorer-->data--> data--> your package name-->databases
Your database should be inside databases folder, and since you're on a rooted device you can get it.
Using ADB
You can use ADB once you have a device connected via USB and with USB debig enabled. To check if your device is correctly connected use:
adb devices
Than get your DB with these commands (you're copying it to SDCARD, and then reading directly from there):
adb -d shell
run-as your.package.name
cat /data/data/your.package.name/databases/database_name.db > /sdcard/your_db_name.db
If you want to do it programmatically have a look to what #Tanis.7x suggests.
The problem has been solved by remove .db from
HafilTC.db
to make it just file name : HafilTC

What am I doing wrong obtaining my current location on my Android App

I'm trying to obtain my current location via GPS, but nothing seems to work, I followed many questions here but with little results...
Here's my code:
private GeoPoint getActualPosition()
{
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
Location current = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
actualLat = (int)(current.getLatitude()*1E6);
actualLong = (int)(current.getLongitude()*1E6);
GeoPoint point = new GeoPoint(actualLat, actualLong);
return point;
}
Now, the "this" part of the method (on requestLocationUpdates) makes reference to the activity who implements the LocationListener interface, where its onLocationChanged method is:
#Override
public void onLocationChanged(Location location) {
actualLat = (int)(location.getLatitude()*1E6);
actualLong = (int)(location.getLongitude()*1E6);
}
My problem is on the current Location line, where "current" is always, always null, and I can't find why.
My manifest has the permissions needed:
<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.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
So I don't really know what is wrong with my code.
Thank you for your time!!
getLastKnownLocation() returns the last cached location. If there was no such location will return null (for e.g if the phone is turned off) If the provider is currently disabled, null is returned
Getting a GPS fix takes time. onLocationChanged() will be called only after getting a proper fix, this time may range from 20 seconds to a few minutes.
Only after onLocationChanged() is called at least once, will getLastKnownLocation() return the last valid location.
are you running the app / your code on an emulator or a physical device ? If its an emulator and you never set the location before (using DDMS view inside eclipse), the location will be null.
hope this helps.
According to the documentation for getLastKnownLocation:
If the provider is currently disabled, null is returned.
So if you don't have GPS enabled on the device you're testing this on, you're going to get null. If you're using the android emulator, please see this stackoverflow post to see how to emulate a particular location.

Categories

Resources