How can I get friends pictore using by android-simple-facebook libraries - android-simple-facebook

I'm using latest android-simple-facebook library
(https://github.com/sromku/android-simple-facebook)
and, want to get friends list with name, picture(profile image).
but i cann't get friends picture at all..
below is my code...
At LoginListener
private OnLoginListener mOnLoginListener = new OnLoginListener() {
#Override
public void onFail(String reason) {
Log.w(TAG, "Failed to login");
}
#Override
public void onException(Throwable throwable) {
Log.e(TAG, "Bad thing happened", throwable);
}
#Override
public void onThinking() {
// show progress bar or something to the user while login is
// happening
}
#Override
public void onLogin() {
PictureAttributes pictureAttributes = Attributes.createPictureAttributes();
pictureAttributes.setType(PictureType.NORMAL);
pictureAttributes.setHeight(500);
pictureAttributes.setWidth(500);
// change the state of the button or do whatever you want
Properties properties = new Properties.Builder()
.add(Properties.ID)
.add(Properties.LAST_NAME)
.add(Properties.PICTURE, pictureAttributes)
.add(Properties.BIRTHDAY).build();
mSimpleFacebook.getFriends(properties, mOnFriendsListener);
}
#Override
public void onNotAcceptingPermissions(Permission.Type type) {
}
};
and the friends listener
// get friends listener
private OnFriendsListener mOnFriendsListener = new OnFriendsListener() {
#Override
public void onFail(String reason) {
// insure that you are logged in before getting the friends
Log.w(TAG, reason);
}
#Override
public void onException(Throwable throwable) {
Log.e(TAG, "Bad thing happened", throwable);
}
#Override
public void onThinking() {
// show progress bar or something to the user while fetching profile
Log.i(TAG, "Thinking...");
}
#Override
public void onComplete(List<Profile> friends) {
for (Profile profile : friends) {
mLists.add(new FriendItem(profile.getName(), profile.getPicture()));
}
mAdapter = new FriendsListAdapter(getActivity());
mFriendsList.setAdapter(mAdapter);
}
};
but the profile object only contains id and name.
should i call get method with async?
or whatever else i can do with getFriends() methods.
The permission lists is likes:
Permission[] permissions = new Permission[] {
Permission.BASIC_INFO,
Permission.USER_CHECKINS,
Permission.USER_EVENTS,
Permission.USER_GROUPS,
Permission.USER_LIKES,
Permission.USER_PHOTOS,
Permission.USER_VIDEOS,
Permission.FRIENDS_EVENTS,
Permission.FRIENDS_PHOTOS,
Permission.PUBLISH_STREAM };

For some reason you have to override onComplete() method inside onLogin to handle with the things that you asked for.
Response will have everything that you asked for in the permissions builder.
I spent a huge amount of time to figure out this. Hope it helps :)
final OnLoginListener onLoginListener = new OnLoginListener() {
#Override
public void onLogin(String accessToken, List<Permission> acceptedPermissions, List<Permission> declinedPermissions) {
OnProfileListener onProfileListener = new OnProfileListener() {
#Override
public void onComplete(final Profile response) {
super.onComplete(response);
.
. // Your code in here`enter code here`
.
});
}

Plz try these permissions:
Permission.PUBLIC_PROFILE,
Permission.USER_BIRTHDAY

Related

Revit Synchronization event

Starting with this...
https://github.com/jeremytammik/RevitLookup/blob/master/CS/EventTrack/Events/ApplicationEvents.cs
I'm trying to add an event listener for a synchronization event. the code below throws an error stating that the m_app is null. Can i not subscribe to this event while Revit is starting up?
I was able to do this before with application.ViewActivated += ..... Im wondering if this has something to do with DB vs UI driven events and when they are allowed to be subscribed to? I just don't know.
namespace RevitModelHealth
{
public class checkHealth : IExternalApplication
{
// Document doc;
static public Autodesk.Revit.ApplicationServices.Application m_app = null;
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
public Result OnStartup(UIControlledApplication application)
{
m_app.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral);
return Result.Succeeded;
}
void m_app_DocumentSavingToCentral(object sender, Autodesk.Revit.DB.Events.DocumentSynchronizingWithCentralEventArgs e)
{
MessageBox.Show("asd","asd");
}
}
}
Here is updated code reflecting my response to the first answer. The message box opens when the document is loaded. No errors are thrown when I try to initialize the synchronization event handlers, however, neither of the message boxes open before or after a synchronization event.
public class checkHealth : IExternalApplication
{
// Document doc;
static public Autodesk.Revit.ApplicationServices.Application m_app;
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
public Result OnStartup(UIControlledApplication application)
{
application.ControlledApplication.DocumentOpened += new EventHandler<DocumentOpenedEventArgs>(app_DocOpened);
return Result.Succeeded;
}
public void app_DocOpened(object sender, DocumentOpenedEventArgs args)
{
MessageBox.Show("asd","asd");
m_app.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral);
m_app.DocumentSynchronizedWithCentral += new EventHandler<Autodesk.Revit.DB.Events.DocumentSynchronizedWithCentralEventArgs>(m_app_DocumentSavedToCentral);
}
void m_app_DocumentSavingToCentral(object sender, Autodesk.Revit.DB.Events.DocumentSynchronizingWithCentralEventArgs e)
{
MessageBox.Show("sync", "sync");
}
void m_app_DocumentSavedToCentral(object sender, Autodesk.Revit.DB.Events.DocumentSynchronizedWithCentralEventArgs e)
{
MessageBox.Show("Doone", "Done");
}
}
this worked.... Thanks largely in part to the SDK sample project EventsMonitor
namespace RevitModelHealth
{
public class checkHealth : IExternalApplication
{
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
public Result OnStartup(UIControlledApplication application)
{
application.ControlledApplication.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(app_syncStart);
application.ControlledApplication.DocumentSynchronizedWithCentral += new EventHandler<DocumentSynchronizedWithCentralEventArgs>(app_syncOver);
return Result.Succeeded;
}
public void app_syncStart(object o ,DocumentSynchronizingWithCentralEventArgs args)
{
MessageBox.Show("","Stasrting");
}
public void app_syncOver(object o,DocumentSynchronizedWithCentralEventArgs args)
{
MessageBox.Show("", "Over");
}
}
}
Try
application.ControlledApplication.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral)
in your OnStartup() method.
The call is failing because instance member m_app is initialized to null.
The UIApplication.ControlledApplication object that raises the DocumentSynchronizingWithCentralEventArgs is being accessible from the parameter to OnStartup.
You can try this:
public void app_DocOpened(object sender, DocumentOpenedEventArgs args)
{
MessageBox.Show("asd","asd");
Autodesk.Revit.ApplicationServices.Application m_app = args.Document.Application;
m_app.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral);
m_app.DocumentSynchronizedWithCentral += new EventHandler<Autodesk.Revit.DB.Events.DocumentSynchronizedWithCentralEventArgs>(m_app_DocumentSavedToCentral);
}

Retrofit error response handling

I am using retrofit 2.3.0 to consume API's in my app but a week ago I started receiving error message and existing code was not able to display error message in UI.
Previously, I was using errorBody.toString() then suddenly after few months I got error and then last week I tried with errorBody.string() but it dodn't work. Now today it's working.
I have attached screenshots of response from server and my error handling also. Here is my code to display error message.
private static void showToastForError(retrofit2.Response<Object> response, int requestType) {
if (response != null && response.errorBody() != null) {
try {
JSONObject jObjError = null;
try {
jObjError = new JSONObject(response.errorBody() != null ? response.errorBody().toString() : "");
Toast.makeText(Application.getAppContext(), jObjError.getString("message"), Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I think you should custom call adapter to handle error.
Here my custom adapter
public final class ErrorHandlingAdapter {
/**
* A callback which offers granular callbacks for various conditions.
*/
public interface MyCallback<T> {
/**
* Called for [200, 300) responses.
*/
void success(Response<T> response);
/**
* Called for 401 responses.
*/
void unauthenticated(Response<?> response);
/**
* Called for [400, 500) responses, except 401.
*/
void clientError(Response<?> response);
/**
* Called for [500, 600) response.
*/
void serverError(Response<?> response);
/**
* Called for network errors while making the call.
*/
void networkError(IOException e);
/**
* Called for unexpected errors while making the call.
*/
void unexpectedError(Throwable t);
}
public interface MyCall<T> {
void cancel();
void enqueue(MyCallback<T> callback);
MyCall<T> clone();
boolean isExcute();
}
public static class ErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
#Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit) {
if (getRawType(returnType) != MyCall.class) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalStateException(
"MyCall must have generic type (e.g., MyCall<ResponseBody>)");
}
Type responseType = getParameterUpperBound(0, (ParameterizedType) returnType);
Executor callbackExecutor = retrofit.callbackExecutor();
return new ErrorHandlingCallAdapter<>(responseType, callbackExecutor);
}
private static final class ErrorHandlingCallAdapter<R> implements CallAdapter<R> {
private final Type responseType;
private final Executor callbackExecutor;
ErrorHandlingCallAdapter(Type responseType, Executor callbackExecutor) {
this.responseType = responseType;
this.callbackExecutor = callbackExecutor;
}
#Override
public Type responseType() {
return responseType;
}
#Override
public <R1> R adapt(Call<R1> call) {
return (R) new MyCallAdapter(call, callbackExecutor);
}
}
}
/**
* Adapts a {#link Call} to {#link MyCall}.
*/
static class MyCallAdapter<T> implements MyCall<T> {
private final Call<T> call;
private final Executor callbackExecutor;
MyCallAdapter(Call<T> call, Executor callbackExecutor) {
this.call = call;
this.callbackExecutor = callbackExecutor;
}
#Override
public void cancel() {
call.cancel();
}
#Override
public void enqueue(final MyCallback<T> callback) {
call.enqueue(new Callback<T>() {
#Override
public void onResponse(Call<T> call, Response<T> response) {
// on that executor by submitting a Runnable. This is left as an exercise for the reader.
callbackExecutor.execute(new Runnable() {
#Override
public void run() {
int code = response.code();
if (code >= 200 && code < 300) {
callback.success(response);
} else if (code == 401) {
if (Storage.getInstance().isLogin())
Storage.getInstance().logout(App.self().getApplicationContext());
} else if (code >= 400 && code < 500) {
callback.clientError(response);
} else if (code >= 500 && code < 600) {
callback.serverError(response);
} else {
callback.unexpectedError(new RuntimeException("Unexpected response " + response));
}
}
});
}
#Override
public void onFailure(Call<T> call, Throwable t) {
// on that executor by submitting a Runnable. This is left as an exercise for the reader.
callbackExecutor.execute(new Runnable() {
#Override
public void run() {
if (t instanceof IOException) {
if (call.isCanceled()) {
return;
}
callback.networkError((IOException) t);
Toast.makeText(App.self(), R.string.error_no_connect_internet, Toast.LENGTH_SHORT).show();
} else {
callback.unexpectedError(t);
}
}
});
}
});
}
#Override
public MyCall<T> clone() {
return new MyCallAdapter<>(call.clone(), callbackExecutor);
}
#Override
public boolean isExcute() {
return call.isExecuted();
}
}
}
Here my config to add custom call adapter
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addCallAdapterFactory(new ErrorHandlingAdapter.ErrorHandlingCallAdapterFactory()) // custom call adapter
.addConverterFactory(GsonConverterFactory.create())
.client(getHeader())
.build();
And handle request, ex:
#GET("api/getSomething")
ErrorHandlingAdapter.MyCall<BaseResponse> getSomething(#Query("param"),...)
Handle response:
ErrorHandlingAdapter.MyCall<BaseResponse> mCalls = ApiUtils.getSomething(...);
mCalls.enqueue(new ErrorHandlingAdapter.MyCallback<BaseResponse>() {
#Override
public void success(Response<BaseResponse> response) {
//handle response
}
#Override
public void unauthenticated(Response<?> response) {
//handle unauthenticated error
}
#Override
public void clientError(Response<?> response) {
//handle clientError error
}
#Override
public void serverError(Response<?> response) {
//handle serverError error
}
#Override
public void networkError(IOException e) {
//handle networkError error
}
#Override
public void unexpectedError(Throwable t) {
//handle unexpectedError error
}
}

GoogleAuthUtil.getToken return null and getting com.google.android.gms.auth.GoogleAuthException: Unknown genrated

This my code:
Main Activity:
public class MainActivity extends Activity implements OnClickListener {
private static final String TAG = "PlayHelloActivity";
// This client id
public static String TYPE_KEY = "997914232893-4f2dggarutugl7r945jblef441mia28f.apps.googleusercontent.com";
private static final String SCOPE = "audience:server:client_id:"+TYPE_KEY+":api_scope:https://www.googleapis.com/auth/userinfo.profile";
private String mEmail;
ProgressDialog mDialog;
String providerName;
private AlertDialog dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.sign_in_button).setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
getUsername();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
if (resultCode == RESULT_OK) {
mEmail = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
Log.e("email", ""+mEmail);
getUsername();
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "You must pick an account", Toast.LENGTH_SHORT).show();
}
} else if ((requestCode == REQUEST_CODE_RECOVER_FROM_AUTH_ERROR ||
requestCode == REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR)
&& resultCode == RESULT_OK) {
handleAuthorizeResult(resultCode, data);
return;
}
}
/** Attempt to get the user name. If the email address isn't known yet,
* then call pickUserAccount() method so the user can pick an account.
*/
private void getUsername() {
if (mEmail == null) {
pickUserAccount();
} else {
if (isDeviceOnline()) {
new GetNameInForeground(MainActivity.this, mEmail, SCOPE).execute();
} else {
Toast.makeText(this, "No network connection available", Toast.LENGTH_SHORT).show();
}
}
}
/** Starts an activity in Google Play Services so the user can pick an account */
private void pickUserAccount() {
String[] accountTypes = new String[]{"com.google"};
Intent intent = AccountPicker.newChooseAccountIntent(null, null,
accountTypes, false, null, null, null, null);
startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);
}
/** Checks whether the device currently has a network connection */
private boolean isDeviceOnline() {
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
return true;
}
return false;
}
private void handleAuthorizeResult(int resultCode, Intent data) {
if (data == null) {
// show("Unknown error, click the button again");
return;
}
if (resultCode == RESULT_OK) {
Log.i(TAG, "Retrying");
new GetNameInForeground(MainActivity.this, mEmail, SCOPE).execute();
return;
}
if (resultCode == RESULT_CANCELED) {
// show("User rejected authorization.");
return;
}
// show("Unknown error, click the button again");
}
/**
* This method is a hook for background threads and async tasks that need to provide the
* user a response UI when an exception occurs.
*/
public void handleException(final Exception e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (e instanceof GooglePlayServicesAvailabilityException) {
// The Google Play services APK is old, disabled, or not present.
// Show a dialog created by Google Play services that allows
// the user to update the APK
int statusCode = ((GooglePlayServicesAvailabilityException)e)
.getConnectionStatusCode();
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(statusCode,
MainActivity.this,
REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR);
dialog.show();
} else if (e instanceof UserRecoverableAuthException) {
// Unable to authenticate, such as when the user has not yet granted
// the app access to the account, but the user can fix this.
// Forward the user to an activity in Google Play services.
Intent intent = ((UserRecoverableAuthException)e).getIntent();
startActivityForResult(intent,
REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR);
}
}
});
}
}
This is requst for getting token :
public class GetNameInForeground extends AbstractGetNameTask {
private static final String REQUEST_CODE_AUTH_GOOGLE_ACCOUNT = null;
public GetNameInForeground(MainActivity activity, String email, String scope) {
super(activity, email, scope);
}
/**
* Get a authentication token if one is not available. If the error is not recoverable then
* it displays the error message on parent activity right away.
*/
#Override
protected String fetchToken() throws IOException {
try {
String token= GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
return token;
} catch ( UserRecoverableAuthException userRecoverableException) {
mActivity.handleException(userRecoverableException);
} catch ( GoogleAuthException fatalException) {
onError("Unrecoverable error" + fatalException.getMessage(), fatalException);
}
catch (IOException e) {
// TODO: handle exception
}
return null;
}
}
If I'm not using client id in scope url then I'll get details of only my account (in which you have register in google developer account)then what is the use of client id.

how to make custom error feedback messages in SignInPanel in Wicket

I am implementing a LoginPage with Wicket, and I am not getting it, how to write the custom Feedback messages, for ex, "Password is wrong", "Username is wrong" or "Accound is locked out" (the last example should be a bit more difficult because it is related to Ldap/Ldap error messages I think.. But I think there is an easier way for the second two, with the properties file of my LoginPage or something like that.. I tried to change the default Wicket "login failed" message, and this through the properties' file of my page, I just added "signFailed=Sign in failed TEST", and it got changed.. but didn't got it how to tell the user why! Pass or username is wrong!
here the implementation:
public class LoginPage extends SampleManagementPage {
private static final long serialVersionUID = -8585718500226951823L;
private SignInPanel signIn;
public LoginPage() {
signIn = new SignInPanel("signInPanel");
add(signIn);
}
}
and my SampleManagementPage extends WebPage!
here the properties' file of LoginPage:
page.title=Login for Sample Management
signInFailed=Sign in failed TEST
The reason why you are able to change only the signFailed error message, is that wicket SignInPanel throws only this particular error in case it's sign-in form fails to authenticate. To see that, you can open the source code of SignInPanel.java.
One way to overcome the problem and produce your own error messages, is write your own sign-in panel. I m not saying it is the only way but it worked for me :)
public class LoginPanel extends Panel {
private static final long serialVersionUID = -1662154893824849377L;
private static final String SIGN_IN_FORM = "signInForm";
private boolean includeRememberMe = true;
private boolean rememberMe = true;
private String password;
private String username;
public LoginPanel(final String id, final boolean includeRememberMe) {
super(id);
this.includeRememberMe = includeRememberMe;
add(new FeedbackPanel("feedback"));
add(new SignInForm(SIGN_IN_FORM));
}
#Override
protected void onConfigure() {
if (isSignedIn() == false) {
IAuthenticationStrategy authenticationStrategy = getApplication().getSecuritySettings().getAuthenticationStrategy();
String[] data = authenticationStrategy.load();
if ((data != null) && (data.length > 1)) {
if (signIn(data[0], data[1])) {
username = data[0];
password = data[1];
onSignInRemembered();
} else {
authenticationStrategy.remove();
}
}
}
super.onConfigure();
}
private boolean signIn(String username, String password) {
return AuthenticatedWebSession.get().signIn(username, password);
}
private boolean userExists(String username) {
return ((MyWebSession) AuthenticatedWebSession.get()).userExists(username);
}
private boolean isSignedIn() {
return AuthenticatedWebSession.get().isSignedIn();
}
protected void onSignInFailed() {
error(getLocalizer().getString("signInFailed", this, "Wrong password"));
}
private void onUserExistsFailed() {
error(getLocalizer().getString("userExistsFailed", this, "User does not exist"));
}
protected void onSignInSucceeded() {
continueToOriginalDestination();
setResponsePage(getApplication().getHomePage());
}
protected void onSignInRemembered() {
continueToOriginalDestination();
throw new RestartResponseException(getApplication().getHomePage());
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public LoginPanel(final String id) {
this(id, true);
}
public final class SignInForm extends StatelessForm<LoginPanel> {
private static final long serialVersionUID = 1L;
public SignInForm(final String id) {
super(id);
setModel(new CompoundPropertyModel<LoginPanel>(LoginPanel.this));
add(new TextField<String>("username"));
add(new PasswordTextField("password"));
WebMarkupContainer rememberMeRow = new WebMarkupContainer("rememberMeRow");
add(rememberMeRow);
rememberMeRow.add(new CheckBox("rememberMe"));
rememberMeRow.setVisible(includeRememberMe);
}
#Override
public final void onSubmit() {
IAuthenticationStrategy strategy = getApplication().getSecuritySettings().getAuthenticationStrategy();
if (!userExists(username)) {
onUserExistsFailed();
strategy.remove();
return;
}
if (signIn(getUsername(), getPassword())) {
if (rememberMe == true) {
strategy.save(username, password);
} else {
strategy.remove();
}
onSignInSucceeded();
} else {
onSignInFailed();
strategy.remove();
}
}
}
}
public class MyWebSession extends AuthenticatedWebSession {
private static final long serialVersionUID = -401924496527311251L;
public MyWebSession(Request request) {
super(request);
}
public boolean userExists(String username) {
// business login
}
#Override
public boolean authenticate(String username, String password) {
// business login
}
#Override
public Roles getRoles() {
Roles roles = new Roles();
roles.add(Roles.USER);
return roles;
}
}

SurfaceView Tutorial problems

I found a tutorial and it looks like this:
package com.djrobotfreak.SVTest;
public class Tutorial2D extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new Panel(this));
}
class Panel extends SurfaceView implements SurfaceHolder.Callback {
private TutorialThread _thread;
public Panel(Context context) {
super(context);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
}
#Override
public void onDraw(Canvas canvas) {
Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(_scratch, 10, 10, null);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
_thread.setRunning(true);
_thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// simply copied from sample application LunarLander:
// we have to tell thread to shut down & wait for it to finish, or else
// it might touch the Surface after we return and explode
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
class TutorialThread extends Thread {
private SurfaceHolder _surfaceHolder;
private Panel _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
and it does not work, no matter what I do. I am trying to convert my code to surfaceview but I cant find any surfaceview programs that even work (besides the android-provided ones). Does anyone know what the error even is saying?
Here is my logcat info: http://shrib.com/oJB5Bxqs
If you get a ClassNotFoundException, you should check the Manifest file.
Click on the Application tab and look on the botton right side under "Attributes for".
If there is a red X mark under your Class Name, then click on the "Name" link and locate the correct class to load.