Android Amazon S3 Upload. error 405 - java

I have been trying for several days to connect Amazon S3 to my Android project. I downloaded the example "https://github.com/awslabs/aws-sdk-android-samples" "S3TransferUtilitySample" and everything works fine on it, I see the files through the aws admin panel.
I copied into my project "Constants.java" with the working settings, also copied "Util.java" without changes.
The purpose of my project is to record the file from the microphone and transfer it to the cloud.
Here is the singleton that should implement this operations :
public class RecorderHelper {
private static final String TAG = "UploadActivity";
private static TransferUtility sTransferUtility;
static private Util util;
static RecorderHelper singleton;
static Boolean RecordStateRecording;
private static MediaRecorder recorder;
private final String RECORD = Environment.getExternalStorageDirectory() + "/record.aac";
String fileName;
private RecorderHelper() {
}
public static RecorderHelper getSingleton(Context context) {
if (singleton == null) {
RecordStateRecording = false;
singleton = new RecorderHelper();
util = new Util();
AmazonS3Client s3Client = util.getS3Client(context);
sTransferUtility = util.getTransferUtility(context);
}
;
return singleton;
}
public void StopRecording() {
try {
if (RecordStateRecording) {
recorder.stop();
recorder.reset();
recorder.release();
AACTrackImpl aacTrack = new AACTrackImpl(new FileDataSourceImpl(RECORD));
if (aacTrack.getSamples().size() > 1000) {
CroppedTrack aacTrackShort = new CroppedTrack(aacTrack, aacTrack.getSamples().size() - 1000, aacTrack.getSamples().size());
Movie movie = new Movie();
movie.addTrack(aacTrackShort);
Container mp4file = new DefaultMp4Builder().build(movie);
FileChannel fc = new FileOutputStream(new File(fileName)).getChannel();
mp4file.writeContainer(fc);
fc.close();
aacTrackShort.close();
aacTrack.close();
} else {
aacTrack.close();
}
}
File file = new File(RECORD);
TransferObserver observer = sTransferUtility.upload(Constants.BUCKET_NAME, file.getName(),
file);
observer.setTransferListener(new UploadListener());
} catch (Exception e) {
Log.e("RECORD", e.getMessage());
}
RecordStateRecording = false;
}
public void StartNewRecording(String UUID) {
StopRecording();
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
fileName = Environment.getExternalStorageDirectory() + "/" + UUID + ".aac";
recorder.setOutputFile(RECORD);
try {
recorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start(); // Recording is now started
RecordStateRecording = true;
}
private class UploadListener implements TransferListener {
// Simply updates the UI list when notified.
#Override
public void onError(int id, Exception e) {
Log.e(TAG, "Error during upload: " + id, e);
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
Log.d(TAG, String.format("onProgressChanged: %d, total: %d, current: %d",
id, bytesTotal, bytesCurrent));
}
#Override
public void onStateChanged(int id, TransferState newState) {
Log.d(TAG, "onStateChanged: " + id + ", " + newState);
}
}
}
However, the file does not appear in the cloud and the listener tells me about the 405 error. Here is the full text.
Can anyone tell me what I'm doing wrong?
Unable to unmarshall error response (Attempt to invoke virtual method
'boolean java.lang.String.equals(java.lang.Object)' on a null object
reference). Response Code: 405, Response Text:
I'm ussing the latest SDK :
compile 'com.amazonaws:aws-android-sdk-s3:2.6.+'
Not sure about stacktrace because because i just get a callback to my listener about the transfer fails.
API 22

Related

Failed to open the CloudDBZone because the object type has not been created

I'm trying to open an (existing) AGConnectCloudDB CloudDBZone with Android Java:
public void openCloudDBZone(String regionName, boolean isAllowToCreate) {
CloudDBZoneConfig config = new CloudDBZoneConfig(regionName, syncProperty, accessProperty);
this.db = AGConnectCloudDB.getInstance(AGConnectInstance.getInstance(), AGConnectAuth.getInstance());
this.db.openCloudDBZone2(config, isAllowToCreate)
.addOnSuccessListener(cloudDBZone -> {
zone = cloudDBZone;
}).addOnFailureListener(e -> {
Log.e(LOG_TAG, e.getMessage());
});
}
This fails with an IllegalStateException from com.huawei.hmf.tasks:
Failed to open the CloudDBZone because the object type has not been created.
I've defined the object-types in the AGConnect console and also as CloudDBZoneObject.
Version number is 1.5.4.300, which has ObjectTypeInfo but no ObjectTypeInfoHelper:
implementation 'com.huawei.agconnect:agconnect-cloud-database:1.5.4.300'
What does this error message mean and what to do about it?
After having found the "Export" button (the screenshot in the documentation doesn't match the GUI, where it can be found inside the menu), I've also found the ObjectTypeInfoHelper.java in the downloaded zip file. Working code for reference:
private AGConnectCloudDB db;
private CloudDBZone zone;
private final CloudDBZoneConfig.CloudDBZoneSyncProperty syncProperty =
CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE;
private final CloudDBZoneConfig.CloudDBZoneAccessProperty accessProperty =
CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC;
private final CloudDBZoneQuery.CloudDBZoneQueryPolicy queryPolicy =
CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_DEFAULT;
/** class ObjectTypeInfoHelper originates from the downloaded zip file. */
public void openCloudDBZone(String zoneName, boolean isAllowToCreate) {
try {
CloudDBZoneConfig config = new CloudDBZoneConfig(zoneName, syncProperty, accessProperty);
this.db = AGConnectCloudDB.getInstance(AGConnectInstance.getInstance(), AGConnectAuth.getInstance());
this.db.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo());
this.db.openCloudDBZone2(config, isAllowToCreate)
.addOnSuccessListener(cloudDBZone -> {
Log.d(LOG_TAG, "CloudDBZone opened: " + zoneName);
zone = cloudDBZone;
}).addOnFailureListener(e -> {
Log.e(LOG_TAG, e.getMessage());
});
} catch (AGConnectCloudDBException e) {
Log.e(LOG_TAG, e.getMessage());
}
}
public void closeCloudDBZone() {
try {
this.db.closeCloudDBZone(this.zone);
Log.d(LOG_TAG, "CloudDBZone closed.");
} catch (AGConnectCloudDBException e) {
Log.w(LOG_TAG, e.getMessage());
}
}
The difference is ObjectTypeInfoHelper.getObjectTypeInfo().
And I've also wrote a TypeConverter, which converts CloudDBZoneObject to BaseObservable (read) and BaseObservable to CloudDBZoneObject (write). Alike this data-binding isn't an issue anymore.

Trying to do resume upload for AWS S3 with java sdk. But it is starting from scratch always to upload

I am trying to upload a file with AWS SDK to demonstrate upload break due to any reason. But I see it is uploading from the beginning always. The code there is pretty straight-forward, but the problem comes with saving persistent obj status so that we can re-use in resuming upload.
Here is my code:
public class Upload2 {
private static final File RESUME_UPLOAD_INFO = new File(System.getProperty("user.home"), "resumeUploadFile");
private static final boolean UPLOAD_HALF_AND_KILL = !RESUME_UPLOAD_INFO.exists();
private static Upload upload;
public static void main(String[] args) throws Exception
{
log("Execution started");
String bucket = "itpc123412";
String key = "s3.txt";
String file_path = "C:\\Users\\rkompelli\\Desktop\\abc3.txt";
File f = new File(file_path);
TransferManager tm = AWSConfiguration.getConnectionTransfer();
System.out.println(RESUME_UPLOAD_INFO.exists());
if (UPLOAD_HALF_AND_KILL)
{
PutObjectRequest por = new PutObjectRequest(bucket, key,f);
log("Starting from scratch");
upload = tm.upload(por, LISTENER);
}
else
{
log("Starting again");
upload = tm.resumeUpload(PersistableUpload.deserializeFrom(new FileInputStream(RESUME_UPLOAD_INFO)));
upload.addProgressListener(LISTENER);
}
log("Total bytes to transfer: " + upload.getProgress().getTotalBytesToTransfer());
log("Bytes transferred: " + upload.getProgress().getBytesTransferred());
upload.waitForCompletion();
log("Done");
tm.shutdownNow();
if (upload.isDone())
RESUME_UPLOAD_INFO.delete();
System.exit(0);
}
private static void log(String msg)
{
System.out.println(DateFormat.getTimeInstance().format(new Date()) + ": " + msg);
}
private static long LAST_LOGGED_BYTES;
private static final S3ProgressListener LISTENER = new S3SyncProgressListener()
{
#Override
public void progressChanged(ProgressEvent pe)
{
long bytes = upload.getProgress().getBytesTransferred();
if (pe.getEventType().isByteCountEvent())
{
if (LAST_LOGGED_BYTES == 0 || bytes - LAST_LOGGED_BYTES > 5)
{
LAST_LOGGED_BYTES = bytes;
log("uploaded: " + NumberFormat.getNumberInstance().format(bytes));
}
}
if (bytes > upload.getProgress().getTotalBytesToTransfer()/2 && UPLOAD_HALF_AND_KILL)
{
log("IF 2 in get progress");
log("Exiting");
System.exit(0);
}
}
#Override
public void onPersistableTransfer(final PersistableTransfer pt)
{
// TODO should not be blocked
try
{
log("Saving upload state");
pt.serialize(new FileOutputStream(RESUME_UPLOAD_INFO));
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
}
I noticed that onPersistableTransfer() event is not executing which has code to serialize the obj.

Using Volley to download image/video to external storage (Android)

i have urls of i got as response from a volley JsonObectRequest. What i want to be able to do is save those images directly into a folder on my external storage so i don't have to load them from the internet anymore. Please keep in mind that download may also include videos...
//Here is the volley code for retrieving the urls
private static final String endpoint = "http://api.androidhive.info/json/glide.json";
//Code to extract image url
JsonArrayRequest req = new JsonArrayRequest(endpoint,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
pDialog.hide();
images.clear();
for (int i = 0; i < response.length(); i++) {
try {
JSONObject object = response.getJSONObject(i);
Image image = new Image();
image.setName(object.getString("name"));
JSONObject url = object.getJSONObject("url");
image.setSmall(url.getString("small"));
image.setMedium(url.getString("medium"));
image.setLarge(url.getString("large"));
image.setTimestamp(object.getString("timestamp"));
} catch (JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
}
}
mAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error: " + error.getMessage());
pDialog.hide();
}
});
Now, how do i request a download so they files are save in my external using volley. Thank you
public boolean storeImages(Bitmap imageBitmap, String fileName, String dirName, int index) {
File file;
if (isExternalStorageWritable() && isExternalStorageReadable()) {
file = storeImageExternalMemory(dirName, albumName, String.valueOf(index));
}
try {
assert file != null;
FileOutputStream out = new FileOutputStream(file);
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
updateImageTable(file, index); // Implement Your own method to update ur DB table, U can access file location from DB table for future use of images
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Convert your downloaded image into bitmap and the save to desired location in cellphone. Then You can reuse image.
private File storeImageExternalMemory(String dirName, String mediaName) {
String packageName = mContext.getPackageName();
File mediaStorageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/Android/data/" + packageName + dirName);
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath(), mediaName + ".jpeg");
return mediaFile;
}
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state);
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
}

Could not render red5 recorded media stream

I have problem of playing back the recorded media file from red5 published stream, following is my code. I could see a file called out.flv is created, but this out.flv can not be played back.
public class Red5ClientTest {
private static Timer timer;
private static RTMPClient client;
private static String sourceStreamName;
private static int videoTs;
private static int audioTs;
private static FLVWriter writer;
private static int bytesRead =0;
public static void main(String[] args) throws IOException {
String sourceHost = "localhost";
int sourcePort = 1935;
String sourceApp = "oflaDemo";
sourceStreamName = "myStream";
timer = new Timer();
client = new RTMPClient();
String path = "c:\\temp\\out.flv";
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
writer = new FLVWriter(file,true);
client.setStreamEventDispatcher(new StreamEventDispatcher());
client.setStreamEventHandler(new INetStreamEventHandler() {
public void onStreamEvent(Notify notify) {
System.out.printf("onStreamEvent: %s\n", notify);
ObjectMap<?, ?> map = (ObjectMap<?, ?>) notify.getCall().getArguments()[0];
String code = (String) map.get("code");
System.out.printf("<:%s\n", code);
if (StatusCodes.NS_PLAY_STREAMNOTFOUND.equals(code)) {
System.out.println("Requested stream was not found");
client.disconnect();
}
else if (StatusCodes.NS_PLAY_UNPUBLISHNOTIFY.equals(code)
|| StatusCodes.NS_PLAY_COMPLETE.equals(code)) {
System.out.println("Source has stopped publishing or play is complete");
client.disconnect();
}
}
});
client.setConnectionClosedHandler(new Runnable() {
public void run() {
if (writer != null) {
writer.close();
}
System.out.println("Source connection has been closed, proxy will be stopped");
System.exit(0);
}
});
client.setExceptionHandler(new ClientExceptionHandler() {
#Override
public void handleException(Throwable throwable) {
throwable.printStackTrace();
System.exit(1);
}
});
// connect the consumer
Map<String, Object> defParams = client.makeDefaultConnectionParams(sourceHost, sourcePort,
sourceApp);
// add pageurl and swfurl
defParams.put("pageUrl", "");
defParams.put("swfUrl", "app:/Red5-StreamRelay.swf");
// indicate for the handshake to generate swf verification data
client.setSwfVerification(true);
// connect the client
client.connect(sourceHost, sourcePort, defParams, new IPendingServiceCallback() {
public void resultReceived(IPendingServiceCall call) {
System.out.println("connectCallback");
ObjectMap<?, ?> map = (ObjectMap<?, ?>) call.getResult();
String code = (String) map.get("code");
if ("NetConnection.Connect.Rejected".equals(code)) {
System.out.printf("Rejected: %s\n", map.get("description"));
client.disconnect();
//proxy.stop();
}
else if ("NetConnection.Connect.Success".equals(code)) {
// 1. Wait for onBWDone
timer.schedule(new BandwidthStatusTask(), 2000L);
Object result = call.getResult();
System.out.println("Red5ClientTest.main()");
}
else {
System.out.printf("Unhandled response code: %s\n", code);
}
}
});
// keep sleeping main thread while the proxy runs
// kill the timer
//timer.cancel();
System.out.println("Stream relay exit");
}
/**
* Handles result from subscribe call.
*/
private static final class SubscribeStreamCallBack implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
Object result = call.getResult();
System.out.println("results came {}" + result);
}
}
private static final class StreamEventDispatcher implements IEventDispatcher {
public void dispatchEvent(IEvent event) {
System.out.println("ClientStream.dispachEvent()" + event.toString());
try {
//RTMPMessage build = RTMPMessage.build((IRTMPEvent) event);
IRTMPEvent rtmpEvent = (IRTMPEvent) event;
ITag tag = new Tag();
tag.setDataType(rtmpEvent.getDataType());
if (rtmpEvent instanceof VideoData) {
videoTs += rtmpEvent.getTimestamp();
tag.setTimestamp(videoTs);
}
else if (rtmpEvent instanceof AudioData) {
audioTs += rtmpEvent.getTimestamp();
tag.setTimestamp(audioTs);
}
IoBuffer data = ((IStreamData) rtmpEvent).getData().asReadOnlyBuffer();
tag.setBodySize(data.limit());
tag.setBody(data);
try {
writer.writeTag(tag);
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("writting....");
}
catch (Exception e) {//IOException
e.printStackTrace();
}
}
}
private static final class BandwidthStatusTask extends TimerTask {
#Override
public void run() {
// check for onBWDone
System.out.println("Bandwidth check done: " + client.isBandwidthCheckDone());
// cancel this task
this.cancel();
// create a task to wait for subscribed
timer.schedule(new PlayStatusTask(), 1000L);
// 2. send FCSubscribe
client.subscribe(new SubscribeStreamCallBack(), new Object[] { sourceStreamName });
}
}
private static final class PlayStatusTask extends TimerTask {
#Override
public void run() {
// checking subscribed
System.out.println("Subscribed: " + client.isSubscribed());
// cancel this task
this.cancel();
// 3. create stream
client.createStream(new CreateStreamCallback());
}
}
/**
* Creates a "stream" via playback, this is the source stream.
*/
private static final class CreateStreamCallback implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
int streamId = ((Number) call.getResult()).intValue();
System.out.println("stream id: " + streamId);
// send our buffer size request
if (sourceStreamName.endsWith(".flv") || sourceStreamName.endsWith(".f4v")
|| sourceStreamName.endsWith(".mp4")) {
client.play(streamId, sourceStreamName, 0, -1);
}
else {
client.play(streamId, sourceStreamName, -1, 0);
}
}
}
}
what could I be doing possibly wrong here?
Finally got it
public class TeqniRTMPClient {
private static final Logger logger = LoggerFactory.getLogger(MyRtmpClient.class);
public static void main(String args[]) throws IOException {
TeqniRTMPClient client = new TeqniRTMPClient("localhost", 1935, "oflaDemo", "myStream");
client.recordStream();
}
private RTMPClient client;
private ITagWriter writer;
private String sourceHost;
private int sourcePort;
private String sourceApp;
private String sourceStreamName;
private int lastTimestamp;
private int startTimestamp = -1;
public TeqniRTMPClient(String sourceHost, int sourcePort, String sourceApp,
String sourceStreamName) {
super();
this.sourceHost = sourceHost;
this.sourcePort = sourcePort;
this.sourceApp = sourceApp;
this.sourceStreamName = sourceStreamName;
}
public void recordStream() throws IOException {
client = new RTMPClient();
String path = "c:\\temp\\out.flv";
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
FLVService flvService = new FLVService();
flvService.setGenerateMetadata(true);
try {
IStreamableFile flv = flvService.getStreamableFile(file);
writer = flv.getWriter();
}
catch (Exception e) {
throw new RuntimeException(e);
}
client.setStreamEventDispatcher(new StreamEventDispatcher());
client.setStreamEventHandler(new INetStreamEventHandler() {
public void onStreamEvent(Notify notify) {
System.out.printf("onStreamEvent: %s\n", notify);
ObjectMap<?, ?> map = (ObjectMap<?, ?>) notify.getCall().getArguments()[0];
String code = (String) map.get("code");
System.out.printf("<:%s\n", code);
if (StatusCodes.NS_PLAY_STREAMNOTFOUND.equals(code)) {
System.out.println("Requested stream was not found");
client.disconnect();
}
else if (StatusCodes.NS_PLAY_UNPUBLISHNOTIFY.equals(code)
|| StatusCodes.NS_PLAY_COMPLETE.equals(code)) {
System.out.println("Source has stopped publishing or play is complete");
client.disconnect();
}
}
});
client.setExceptionHandler(new ClientExceptionHandler() {
#Override
public void handleException(Throwable throwable) {
throwable.printStackTrace();
System.exit(1);
}
});
client.setConnectionClosedHandler(new Runnable() {
public void run() {
if (writer != null) {
writer.close();
}
System.out.println("Source connection has been closed, proxy will be stopped");
System.exit(0);
}
});
// connect the consumer
Map<String, Object> defParams = client.makeDefaultConnectionParams(sourceHost, sourcePort,
sourceApp);
// add pageurl and swfurl
defParams.put("pageUrl", "");
defParams.put("swfUrl", "app:/Red5-StreamRelay.swf");
// indicate for the handshake to generate swf verification data
client.setSwfVerification(true);
// connect the client
client.connect(sourceHost, sourcePort, defParams, new IPendingServiceCallback() {
public void resultReceived(IPendingServiceCall call) {
System.out.println("connectCallback");
ObjectMap<?, ?> map = (ObjectMap<?, ?>) call.getResult();
String code = (String) map.get("code");
if ("NetConnection.Connect.Rejected".equals(code)) {
System.out.printf("Rejected: %s\n", map.get("description"));
client.disconnect();
}
else if ("NetConnection.Connect.Success".equals(code)) {
// 1. Wait for onBWDone
client.createStream(new CreateStreamCallback());
Object result = call.getResult();
System.out.println("Red5ClientTest.main()");
}
else {
System.out.printf("Unhandled response code: %s\n", code);
}
}
});
}
class CreateStreamCallback implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
int streamId = ((Number) call.getResult()).intValue();
System.out.println("stream id: " + streamId);
// send our buffer size request
if (sourceStreamName.endsWith(".flv") || sourceStreamName.endsWith(".f4v")
|| sourceStreamName.endsWith(".mp4")) {
client.play(streamId, sourceStreamName, 0, -1);
}
else {
client.play(streamId, sourceStreamName, -1, 0);
}
}
}
class StreamEventDispatcher implements IEventDispatcher {
private int videoTs;
private int audioTs;
public void dispatchEvent(IEvent event) {
System.out.println("ClientStream.dispachEvent()" + event.toString());
try {
IRTMPEvent rtmpEvent = (IRTMPEvent) event;
logger.debug("rtmp event: " + rtmpEvent.getHeader() + ", "
+ rtmpEvent.getClass().getSimpleName());
if (!(rtmpEvent instanceof IStreamData)) {
logger.debug("skipping non stream data");
return;
}
if (rtmpEvent.getHeader().getSize() == 0) {
logger.debug("skipping event where size == 0");
return;
}
byte dataType = rtmpEvent.getDataType();
ITag tag = new Tag();
tag.setDataType(dataType);
if (rtmpEvent instanceof VideoData) {
VideoData video = (VideoData) rtmpEvent;
FrameType frameType = video.getFrameType();
videoTs += rtmpEvent.getTimestamp();
tag.setTimestamp(videoTs);
}
else if (rtmpEvent instanceof AudioData) {
audioTs += rtmpEvent.getTimestamp();
tag.setTimestamp(audioTs);
}
IoBuffer data = ((IStreamData) rtmpEvent).getData().asReadOnlyBuffer();
tag.setBodySize(data.limit());
tag.setBody(data);
try {
writer.writeTag(tag);
}
catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("writting....");
}
catch (Exception e) {//IOException
e.printStackTrace();
}
}
}
}

Difficulty Trying to Install and Update App

I referenced a question here about how one might approach (outside of Google Play) having an app essentially update itself. For testing, I simply wanted to try to see if I could get it to download and install. Unfortunately, I get a parse error.
I would greatly appreciate any help:
A snippet from the class that calls the AsyncTask class:
public class downloadReceiver extends BroadcastReceiver {
private Context context;
private long localUpdate;
private long remoteUpdate = 20;
#Override
public void onReceive(final Context c, Intent i) {
new Thread(new Runnable() {
#Override
public void run() {
SharedPreferences preferences = c.getSharedPreferences("config", c.MODE_PRIVATE);
final String store = preferences.getString("store", "");
final String id = preferences.getString("id", "");
final long lastUpdated = preferences.getLong("updated", 0);
// autoUpdate app
appUpdater updater = new appUpdater(c);
try {
updater.execute(new URL("http://midamcorp.com/myApp.php"));
} catch (Exception e) {Log.e(this.getClass().toString(), " " + e.getMessage()); }
and the appUpdater class:
public class appUpdater extends AsyncTask<URL, String, String> {
private Context c;
public appUpdater(Context context) {
this.c = context;
}
protected String doInBackground(URL... appUrl) {
String location = c.getFilesDir() + "/app.apk";
try {
URL url = appUrl[0];
URLConnection con = url.openConnection();
con.connect();
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(location);
byte[] buffer = new byte[1024];
int read = 0;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.close();
input.close();
} catch(Exception e){
Log.e(this.getClass().toString(), " " + e.getMessage());
}
return location;
}
#Override
protected void onPostExecute(String saveLocation) {
Intent i = new Intent();
i.setAction(Intent.ACTION_VIEW);
Log.i("Location of app is: ", " " + saveLocation);
i.setDataAndType(Uri.fromFile(new File(saveLocation)), "application/vnd.android.package-archive");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
c.startActivity(i);
}
}
Please note, the URL is linked to a PHP file that forces a download because the server I have it on has trouble with .apk files.
Your primary problem is that the installer does not have access to your portion of internal storage (getFilesDir()). Use external storage.
I also recommend that you call flush(), getFD().sync(), and close() in succession on your FileOutputStream, before trying to install the app.

Categories

Resources