I'm stuck on one problem... I try to load FB profile pic in Android:
// Request user data and show the results
Request.executeMeRequestAsync(session, new Request.GraphUserCallback()
{
public void onCompleted(GraphUser user, Response response) {
if (user != null)
{
userInfoTextView.setText(fb.buildUserInfoDisplay(user));
profilePhoto.setImageBitmap(fb.getUserPic());
}
}
});
The problem is, I get NetworkOnMainThreadException. Now I know, that I have to use AsyncTask, but if I do, I can't modify the view, because it was not created on that thread. Any ideas?
for network on main thread exception write this code before setting your layout file
if (android.os.Build.VERSION.SDK_INT > 9(minimum sdk target that you have given in your manifest file))
{
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Related
I have an app that users can upload file. Right now it works.
They can upload files and it received in server side.
Now I want show upload percent to users while uploading.
I used below code to upload files on server.
here is my java code:
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
new MaterialFilePicker().
withActivity(AddActivity.this).
withRequestCode(10).
start();
}
catch (Exception e){
return;
}
}
});
and this is my method:
ProgressDialog progress;
#Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
if (requestCode==10 && resultCode==RESULT_OK){
progress = new ProgressDialog(AddActivity.this);
progress.setTitle("Uploading");
progress.setMessage("please wait...");
progress.show();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
File f = new File(data.getStringExtra(FilePickerActivity.RESULT_FILE_PATH));
String content_type = getMimeType(f.getPath());
String file_path = f.getAbsolutePath();
file_size = String.valueOf(f.length()/1024);
OkHttpClient client = new OkHttpClient();
RequestBody file_body = RequestBody.create(MediaType.parse(content_type),f);
RequestBody request_body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("type",content_type)
.addFormDataPart("upload_file",code+file_path.substring(file_path.lastIndexOf(".")),file_body)
.build();
code2 = code+file_path.substring(file_path.lastIndexOf("."));
Request request = new Request.Builder()
.url("http://api.mysite.com/api/uploadfile")
.post(request_body)
.build();
try {
Response response = client.newCall(request).execute();
Log.d("msg",request_body.toString());
Log.d("msg",f.getPath().toString());
Log.d("msg",getMimeType(f.getPath()));
Log.d("msg33",code+file_path.substring(file_path.lastIndexOf(".")));
if (!response.isSuccessful()){
throw new IOException(("Error:"+response));
}
progress.dismiss();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
}
}
Please help me to add upload percentage.
Thank you
You are doing a lot of things wrong here:
Logic responsible for uploading file should not be located in onActivityResult()
You should seperate it into different method
Using thread like that is not a good idea
If you want to upload file or large file you should do it in IntentService class (You will have to create Your own class and extend IntentService), it is something that is meant for things like that. I suggest You to learn about Retrofit2 and OkHttp library cause it will make it a lot of easier.
An example where you can find a one of the ways how to do it is here: Is it possible to show progress bar when upload image via Retrofit 2?
Asking ppl at stackoverflow to write code completly for you is not a good way to improve your skills. Check this link which I gave You.
Good luck
EDIT:
Android Services: http://www.vogella.com/tutorials/AndroidServices/article.html and https://developer.android.com/training/run-background-service/create-service
Retrofit 2: http://www.vogella.com/tutorials/Retrofit/article.html
OkHttp: https://www.journaldev.com/13629/okhttp-android-example-tutorial
Sample: Is it possible to show progress bar when upload image via Retrofit 2?
These link provides all the information You need in order to write this functionality. I don't have videos on YouTube with things like this. I'm never using YouTube to get this kind of information.
ProgressDialog is showing only if I am sending text but when I sent images it gave me an error which tells that there are lot of activities running or the app can't handle all of it, the solution is to add StrictMode.ThreadPolicy before invoking those tasks but the problem is ProgressDialog is not showing anymore which is important to tell the user about the ongoing process.
I believe it is StrictMode.ThreadPolicy that causes the ProgressDialog to disappear. I am not using Asynctask that's why I haven't found solution on the Internet yet because most of them are using it. I am also planning to use Asynctask but my boss did not approve it, he's afraid that it will ruin the app.
{
private void upLoadImage(String path){
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().penaltyDialog().build();
StrictMode.setThreadPolicy(policy);
uploadMedia(path);}}
{
private void uploadMedia(String path) {
String ImageName = "image_name";
String ImagePath = "image_path";
try {
String charset = "UTF-8";
File uploadFile1 = new File(path);
String requestURL= "http://myurl";
MultipartUtility multipart = new MultipartUtility(requestURL,
charset);
multipart.addFormField(ImageName, "iName");
multipart.addFormField(ImagePath, "iPath");
multipart.addFilePart("uploadedfile", uploadFile1);
List<String> response = multipart.finish();
Log.v("rht", "SERVER REPLIED:");
for (String line : response) {
Log.v("rht", "Line : "+line);
if(line=="true"||line=="Saved"){
progressDialog.dismiss();
}
}
// Toast.makeText(this, ""+response, Toast.LENGTH_SHORT).show();
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}
if you access Network in UI thread the error is shown.You cannot do the network operations in the main thread.It is better to use a worker thread or ayntask. But if you are willing to accept the consequences, and must do network operations on the main thread, you can override the default behavior:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
I'm developing an Android app which uses Facebook Login. Login's working fine and I'm able to get back info via Facebook Graph API calls.
I'm trying upload a string to my Firebase database and the string (titled parentFirstNameFromFacebook) is the first name of the user who signed into Facebook. I'm trying to eventually upload a parent object with parentFirstNameFromFacebook in its setName() method.
doneCreatingNameAndPasswordFAB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
gettingTextFromNameAndPasswordEditTexts();
//region creating new Parent object and setting required variables
Parent coOpCreatingParent = new Parent();
coOpCreatingParent.setCoopCreator(true);
coOpCreatingParent.setNumOfHoursOwned(0);
Bundle params = new Bundle();
params.putString("fields", "id,first_name");
new GraphRequest(AccessToken.getCurrentAccessToken(), "me", params, HttpMethod.GET,
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
if (response != null) {
try {
JSONObject data = response.getJSONObject();
parentFirstNameFromFacebook = data.getString("first_name");
SharedPreferences fBookSharedPref;
SharedPreferences.Editor editor;
fBookSharedPref = getSharedPreferences(Constants.FBOOK_NAME_SHARED_PREF, Context.MODE_PRIVATE);
editor = fBookSharedPref.edit();
editor.putString(Constants.FBOOK_NAME_SHARED_PREF, parentFirstNameFromFacebook);
editor.apply();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).executeAsync();
SharedPreferences fBookSharedPref = getSharedPreferences(Constants.FBOOK_NAME_SHARED_PREF, Context.MODE_PRIVATE);
fbookFirstNameForUpload = fBookSharedPref.getString(Constants.FBOOK_NAME_SHARED_PREF, null);
coOpCreatingParent.setName(fbookFirstNameForUpload);
getProfileImageUrlFromFBookGraph();
coOpCreatingParent.setImageUrl(parentImageIDFromFBookGraph);
ArrayList<Child> newChildArrayList = new ArrayList<>();
coOpCreatingParent.setChildren(newChildArrayList);
//endregion
//region creating new ArrayList<Parent> adding Parent object from above
ArrayList<Parent> coOpParentArrayList = new ArrayList<>();
coOpParentArrayList.add(coOpCreatingParent);
//endregion
getReferenceOfCoOpBeingCreated();
//region uploading entire new Co-Op object to Firebase
CoOp coOpObjectBeingUploaded = new CoOp(coOpKey, enteredNewCoOpPassword, enteredNewCoOpName, coOpParentArrayList);
referenceOfCoOp.setValue(coOpObjectBeingUploaded);
//endregion
//region going to AddChildren Activity with Co-Op key in intent
Intent intentForNewActivity = new Intent(getBaseContext(), AddChildrenActivity.class);
intentForNewActivity.putExtra(Constants.CO_OP_REFERENCE_TO_CHILD_ACTIVITY_KEY, coOpKey);
startActivity(intentForNewActivity);
//endregion
}
});
In the Firebase screenshot below, parentsInCoOp is an ArrayList and the 0 below it is the Parent object. I'm trying to set a name and Facebook URL string as other variables for that Parent object.
Firebase screenshot
Whatever I do, the name doesn't show up on Firebase! I'm not sure what I'm doing wrong!
I also tried using Shared Preferences in case there's an issue with setting parentFirstNameFromFacebook within the Facebook call's onCompleted() method. I put parentFirstNameFromFacebook in SharedPref and then got it out to pass it through parent.setName().
Once I successfully upload the first name, then I'll do the same process for the fbook image URl string.
Anyone have any advice? Thanks!
You are performing the Facebook API GraphRequest using the executeAsync() method. The request is processed on a separate thread and the onComplete() response is received asynchronously. I don't use the Facebook API, but am guessing the request requires communication with the Facebook servers and will require many milliseconds to deliver a response.
The result is that these statements
fbookFirstNameForUpload =
fBookSharedPref.getString(Constants.FBOOK_NAME_SHARED_PREF, null);
coOpCreatingParent.setName(fbookFirstNameForUpload);
execute before the statements in the callback have executed and stored the name in preferences.
I can not find a working way to send a picture on the wall.
My code is that I do not.
Bundle postParams = new Bundle();
postParams.putByteArray("image", byteArray);
postParams.putString("message", "A wall picture");
Session session = Session.getActiveSession();
if (session != null) {
Log.e("Session", "don t null");
Request request = new Request(session, "me/feed", postParams,
HttpMethod.POST);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
I've never sent pictures from the phone, but from a server using an image link. I'll put this code in case it helps you since most of the logic is similar.
final Bundle parameters = new Bundle();
parameters.putString("name", getString(R.string.app_name));
parameters.putString("caption", "haha");
parameters.putString("link", "www.google.com");
parameters.putByteArray("picture", byteArray);//I took this one from your code. My key is "picture" instead of "image"
Session.openActiveSession(this, true, new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
new FeedDialogBuilder(EndGameActivity.this, session, parameters).build().show();
//you can try this one instead of the one above if you want, but both work well
//Request.newMeRequest(session, new Request.GraphUserCallback() {
//
// #Override
// public void onCompleted(GraphUser user, Response response) {
// final Session session = Session.getActiveSession();
// new FeedDialogBuilder(EndGameActivity.this, session, parameters).build().show();
// }
//}).executeAsync();
}
}
});
This code will only work in the last Facebook SDK 3.5 since Request.newMeRequest was recently introduced and should be used instead of Request.executeMeRequestAsync, which has been deprecated.
Also notice that the key I use is "picture" instead of "image". Maybe that's the problem with your code.
But I do it inside a onClick event when the user touch a button. Why do you need it in your onCreate method?
I'm trying very simply to test the 3.0 Facebook get started guide. https://developers.facebook.com/docs/getting-started/facebook-sdk-for-android/3.0/
I have had some problems with imports and references but I don't know it that's relevant. The issue I'm having is when I try to run the test Activity ant get this error:
Could not find class 'com.test1.test2.FacebookLogin$1', referenced from method com.test1.test2.FacebookLogin.onCreate
Code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_facebook_login);
//Error occurs here when I use 'this'
Session.openActiveSession(this, true, new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
// make request to the /me API
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
TextView welcome = (TextView) findViewById(R.id.welcome);
welcome.setText("Hello " + user.getName() + "!");
}
}
});
}
}
});
}
How can I get a NoClassDefFoundError when I use this?
UPDATE:
After testing with the Scrumtious tutorial https://developers.facebook.com/docs/tutorials/androidsdk/3.0/scrumptious/authenticate/ as well I'm getting the same error when I call the Session.StatusCallback() method. I still don't know what my problem is though.
Thanks for the help
Maybe you updated to Android sdk tools revision 22. There is an issue there. You have to add the libraries you use in the export path. Check:
Android Sdk tools Revision 22 issue?