I am developing a camera app. I want to take pictures and send them to Server.
I have 3 Classes.
SimpleCamera - handles camera and gets images in byte[] form
SendInfo - handles HTTP request
MainActivity - middleman for above to happen
When I open MainActivity a new instance of SimpleCamera is created and preview is reflected on a textureView. When I click a button on MainActivity getImageBytes method of SimpleCamera returns image data as a byte Array. Then I create an instance of SendInfo for sending this data to server.
The problem starts here: I trigger getImageBytes() and move imageBytes to my byte Array. Then put this array into request body in SendInfo like below.
private void clickFunciton(){
byte[] imageBytes = simpleCamera.getImageBytes();
SendInfo si = new SendInfo();
si.imageBytes = imageBytes;
si.send();
}
But si.send() block is triggered before getImageBytes(). That's why I get Array is null error. What approach should I consider?
Related
I have an Android application, which has a lot of articles. If you open an article a new activity is created. Now there is a part in the activity which is always the same, but it send a request to the server to get the data. I was thinking to make a fragment which will load the data only once (probably in MainActivity) and show it to all activities. Is this possible and how do I do it?
I also tried creating a fragment, but it still loads the data every time a new activity is created. Here is the XML code.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/textView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000" />
<!-- There is more layout, but I don't think it is needed for now -->
</RelativeLayout>
And Java
private class getMessage extends AsyncTask<Void , Void, Void>{
#Override
protected Void doInBackground(Void... params) {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httppost = new HttpGet("http:///www.example.com");
HttpResponse response;
try {
response = httpclient.execute(httppost);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
InputStream is = buf.getContent();
BufferedReader r = new BufferedReader(new InputStreamReader(is));
total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line + "\n");
}
}
catch (ClientProtocolException e) {}
catch (IOException e) {}
return null;
}
#Override
protected void onPostExecute(Void args){
try{
textView.setText(total.toString());
}
catch(Exception e){}
}
}
And the code to add the fragment
FragmentManager fragMan = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragTransaction = fragMan.beginTransaction();
Fragment fragment = new Fragment();
fragTransaction.add(R.id.fragment_replace, fragment);
fragTransaction.commit();
Fragments belong to only one activity. After you commit() the transaction, that fragment "belongs" to that activity.
If you want a higher level sharing or network related data, I suggest you to implement it in a Bound Service and have activities or fragments to get this data directly from the Service
If you have only one activity in your application, it is possible. But you cant show the loaded fragment in many activities.
Only after adding the fragment to the container, you can attach and detach a fragment.
You are trying to cache data using Fragment, but as you can see at documentation:
A Fragment represents a behavior or a portion of user interface in an
Activity
source: Fragments
Fragment should be used to avoid "copy-paste" in user interface code.
But you are trying to cache the data from network. This is not mission of Fragment. This is not Tier when you should process data. At Fragment you should only load already cached data.
I can recomend you choose one of next solutions:
1). Use SQLite database to cache data.
If you want to cache data in SQLite, I recomend you use pattern, which Virgil Dobjanschi described at Google I/O conference in 2010(link to video here)
Also, I think this example may be helpful for implementing this pattern.
2). Use some network libraries, which can help you to cache data
Robospice - is a modular android library that makes writing asynchronous long running tasks easy. It is specialized in network requests, supports caching and offers REST requests out-of-the box using extension modules.
link: Robospice
example project: Robospice+Retrofit
Short description how to cache:
getSpiceManager().execute(githubRequest, "github", DurationInMillis.ONE_MINUTE, new ListContributorRequestListener());
"github" - is a key. DurationInMillis.ONE_MINUTE - time while cached data will be actual. This means, that if you are executed this request first time, data will be loaded from network. If you are executed this request second time during 1 minute, then data will be loaded from local cache.
Possible values of DurationInMillis from docs:
**Field Summary**
static long ALWAYS
Deprecated.
static long ALWAYS_EXPIRED
Data in cache will never be returned, a network call will always be performed.
static long ALWAYS_RETURNED
Data in cache will always be returned.
static long NEVER
Deprecated.
static long ONE_DAY
static long ONE_HOUR
static long ONE_MINUTE
static long ONE_SECOND
static long ONE_WEEK
OkHttp - from docs:
OkHttp is an HTTP client that’s efficient by default:
HTTP/2 and SPDY support allows all requests to the same host to share
a socket.
Connection pooling reduces request latency (if SPDY isn’t
available).
Transparent GZIP shrinks download sizes.
Response caching avoids the network completely for repeat requests.
link: OkHttp
example project: samples
Short description how to cache:
// Create an HTTP client that uses a cache on the file system. Android applications should use
// their Context to get a cache directory.
OkHttpClient okHttpClient = new OkHttpClient();
File cacheDir = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());
HttpResponseCache cache = new HttpResponseCache(cacheDir, 1024);
okHttpClient.setResponseCache(cache);
Full example here
In my android app I want to implement a visualizer graph linked to a Media Player following this idea. I use a service to manage my background streaming with MediaPlayer. The problem comes with the transmission of my MediaPlayer object to my fragment. I need to have it there because is where the link occurs:
// We need to link the visualizer view to the media player so that
// it displays something
mVisualizerView = (VisualizerView) findViewById(R.id.visualizerView);
mVisualizerView.link(mPlayer);
In summary, I need to send MediaPlayer object from my service to my fragment. Any idea?
Hello I am creating software which allow files to be uploaded, my software has a chat client which will create a instance of a file uploader class, this file uploader class will take the file from the file chooser, convert it to byte and upload it to the sql database. so essentially I have a main chat client which contains a text area for chat to be show in. I have main chat windows which displays contacts. when the user double clicks on a contact the chat client opens up:
private void jList1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
if (evt.getClickCount() == 2) {
String userID = lbluserID.getText();
String selectedContact = jList1.getSelectedValue().toString();
ChatClient chatClientObject = new ChatClient(selectedContact, userID);
ChatClient.runchatClient(selectedContact, userID);
}
}
within this chat client I have placed a button which allows the selection of the file. the dbconnect class will upload the file to the server, once this is done I need a message to appear in the chat client text area displaying that the file has been uploaded. I have tried to make a instance of the chat client in the dbconnect class and then call a method to output the message how ever this gives me errors. what I really want to do is allow my program to open the chat client for the contact the user clicks on and also be able to return the message to the same chat client instead of creating a new instance.
I hope my question is clear as it is pretty hard to explain.... for example, If i click on "Ben" in the main client a chat client will open for "ben" this chat client contains a text area. when i have finished uploading the file which is done by the dbconnect class I want the string message "file sent" to be returned to the chat I have open with "ben".
you said 'I have tried to make a instance of the chat client in the dbconnect class and then call a method to output the message how ever this gives me errors.'
Don't create new instance of client to send file completion message, you need to be use the same instance that was created at the time of client instantiated. So that at the time of client instantiated 1st time you need to hold that reference in global variable. And call method using this instance to display message.
It could help you.
I am most concerned about Performance issue and don't want users to wait for progress.
I have a chatActivity, where i show a ListView.
Here i send a chatMessage
Chats chat = new Chats(chatBox.getText().toString(),Chats.TYPE_MINE, dt.format(now));
chat.personId = chatee.getMyId();
chat.isDelievered = Chats.DELIEVERED_NONE;
chats.add(chat);
mAdapter.notifyDataSetChanged();
Notice that Chat delievery is set to NONE Right now. So basically the message is being added to the Chat List even its not delivered yet.
Now on back thread here is what's happening
It takes few seconds to send message where i do this
boolean bool = sendMessage(m);
if (bool)
chatee.isDelievered = Chats.DELIEVERED_DONE; (MESSAGE SENT)
if (chatee.isDelievered == Chats.DELIEVERED_DONE)
{
app.mDbHelper.saveMessage(chatee); // SAVING TO DATABASE
Intent i = new Intent(Constants.REFRESH_NOTIF).putExtra("refresh",Constants.REFRESH_NOTIF);
context.sendBroadcast(i);
}
It will send a broadcast to the activity.
Now here is the problem.
Broadcast call this function
public void callUIMethodForRefresh(Intent intent)
{
String ref = intent.getStringExtra("refresh");
if (ref == null)
{
}
else if (ref.equals(Constants.REFRESH_NOTIF))
{
}
}
Here i am confused of how can I reset that previous Chat object added to my List.
Points to be noted , i can be sending messages at a very fast speed and the refresh could be called for an old message whereas a new message is already typed.
ONE way is i make a For loop and check for all the "ChatList" array for the message sent and then replace its delivery notice, but again this is very low performance incase i have 1000+ objects in the list.
Is there any way, i can attach the sqlite database with my listView adapter that automatically detects the changes and reset the listView etc and etc?
What could be the best strategies here to avoid performance issues.
I would suggest looking into ContentProviders and Loaders (specifically a CusorLoader). Combining these with a CursorAdapter, you can use the ContentProvider which inserts/deletes/updates your sqlite database and notifies your loader to reload it's dataset and update the CursorAdapter/ListView.
As I talk about befor I'm using to jQuery to refresh / update a webcam image.
This works just fine if you wanna update the image every 5th or 10sec.
But when your gonna do a stream with 10-15fps it gets into problems with most browsers
it seems. The problem seem to be that it sends a request befor the first one was done.
Is there a way to wait for the first request to be done befor sending a new update request for the webcam image? Because to me it seems to stack up requests if there is alittle delay on the server with the image.
Sorry if I did explain it alittle bad but... I'm norwegian and blode. Not the best combination. :)
Webcam Image is a single url
ex. http://www.ohoynothere.com/image.jpg
Old code I use.
$(document).ready(function() {
setInterval('updateCamera()',3000);
});
function updateCamera() {
$('.online2').each(function() {
var url = $(this).attr('src').split('&')[0];
$(this).attr('src', url + '&rand=' + new Date().getTime());
})
}
Definitely!
It sounds like your best bet would be to use the jQuery.ajax() method ( http://api.jquery.com/jQuery.ajax/ ) or .get() method to chain your requests. Basically, you want a JavaScript function that does a request for the image using the .ajax() call. In the response handler, simply call the function again:
function getMyImage() {
jQuery.get(image_url, function(response) {
jQuery('#img-name').attr('src', response);
getMyImage();
});
}
Whenever getMyImage successfully returns the image's src value from the webcam, it will immediately go out and try to retrieve a new image, but not before the previous one is loaded.
If I haven't understood what you're trying to do, please let me know. It would be helpful to know more about how the webcam image is retrieved (i.e. is it the same image src returned every time, etc.).