I tried to upload a file on firebase cloud from MainActivity, i made when application is destoryed it start background services and make a file contains StorageReference.toString()
and in background service i used getReferenceFromUrl(string)
To complete the uploading and i used after it
List<UploadTask> tasks = storage.getActiveTasks();
and i used Toast.makeText(this, "tasks: " + tasks.size(), 0).show();
and it shows tasks = 0
Why? And the upload doesnt complete yet
MainActivity
import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ClipData;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.gms.tasks.Task;
import com.google.android.material.appbar.AppBarLayout;
import com.google.firebase.FirebaseApp;
import com.google.firebase.storage.UploadTask;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileWriter;
import java.io.File;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
public final int REQ_CD_IM = 101;
private Toolbar _toolbar;
private AppBarLayout _app_bar;
private CoordinatorLayout _coordinator;
private String image = "";
private UploadSaveed upload;
private String url = "";
private ImageView imageview1;
private Button button1;
private ProgressBar progressbar1;
private TextView textview1;
private AlertDialog.Builder d;
private Intent im = new Intent(Intent.ACTION_GET_CONTENT);
#Override
protected void onCreate(Bundle _savedInstanceState) {
super.onCreate(_savedInstanceState);
setContentView(R.layout.main);
initialize(_savedInstanceState);
upload = new UploadSaveed(getApplicationContext());
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.READ_EXTERNAL_STORAGE }, 1000);
} else {
initializeLogic();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1000) {
initializeLogic();
}
}
private void initialize(Bundle _savedInstanceState) {
_app_bar = findViewById(R.id._app_bar);
_coordinator = findViewById(R.id._coordinator);
_toolbar = findViewById(R.id._toolbar);
setSupportActionBar(_toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
_toolbar.setNavigationOnClickListener((view) -> {
onBackPressed();
});
imageview1 = findViewById(R.id.imageview1);
button1 = findViewById(R.id.button1);
progressbar1 = findViewById(R.id.progressbar1);
textview1 = findViewById(R.id.textview1);
d = new AlertDialog.Builder(this);
im.setType("*/*");
im.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
imageview1.setOnClickListener((view) -> {
startActivityForResult(im, REQ_CD_IM);
});
button1.setOnClickListener((view) -> {
upload.setUploadListener(new UploadSaveed.UploadSavedListener() {
#Override
public void onFailureListener(Exception e) {
SketchwareUtil.showMessage(getApplicationContext(), e.toString());
}
#Override
public void onProgressListener(UploadTask.TaskSnapshot task) {
double progress = (100 * task.getBytesTransferred()) / task.getTotalByteCount();
progressbar1.setProgress((int) progress);
double bytes = task.getBytesTransferred();
SketchwareUtil.showMessage(getApplicationContext(), "transferred : " + bytes);
if (upload.getUploadUrl() != null) {
url = upload.getUploadUrl();
}
}
#Override
public void onPausedListener(UploadTask.TaskSnapshot task) {
SketchwareUtil.showMessage(getApplicationContext(), "your uploading was paused");
}
#Override
public void onSuccessListener(UploadTask.TaskSnapshot task) {
Task<Uri> taskk = task.getStorage().getDownloadUrl();
while (!taskk.isSuccessful())
;
textview1.setText(taskk.getResult().toString());
SketchwareUtil.showMessage(getApplicationContext(), "finished");
}
});
upload.UploadFile(image);
});
}
private void initializeLogic() {
if (!isMyServiceRunning(UploadService.class)) {
} else {
stopService(new Intent(getApplicationContext(), UploadService.class));
stopService(new Intent(getApplicationContext(), UploadSaveed.class));
}
d.setTitle("AutoStart");
d.setMessage("You must enable autostart for application to Work in background.");
d.setPositiveButton("enable", (dialog, which) -> {
try {
final Intent intent = new Intent();
String manufacturer = Build.MANUFACTURER.toLowerCase();
if ("xiaomi".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.miui.securitycenter",
"com.miui.permcenter.autostart.AutoStartManagementActivity"));
} else if ("oppo".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.coloros.safecenter",
"com.coloros.safecenter.permission.startup.StartupAppListActivity"));
// intent.setComponent(new ComponentName("com.coloros.oppoguardelf",
// "com.coloros.powermanager.fuelgaue.PowerConsumptionActivity"));
} else if ("vivo".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.vivo.permissionmanager",
"com.vivo.permissionmanager.activity.BgStartUpManagerActivity"));
} else if ("huawei".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.huawei.systemmanager",
"com.huawei.systemmanager.optimize.process.ProtectActivity"));
} else if ("Letv".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.letv.android.letvsafe",
"com.letv.android.letvsafe.AutobootManageActivity"));
} else if ("Honor".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.huawei.systemmanager",
"com.huawei.systemmanager.optimize.process.ProtectActivity"));
} else {
return;
}
startActivity(intent);
SketchwareUtil.showMessage(getApplicationContext(),
"please enable auto start to background application");
} catch (Exception e) {
e.printStackTrace();
}
});
d.setNegativeButton("I already enabled it", (dialog, which) -> {
});
d.create().show();
}
#Override
protected void onActivityResult(int _requestCode, int _resultCode, Intent _data) {
super.onActivityResult(_requestCode, _resultCode, _data);
switch (_requestCode) {
case REQ_CD_IM:
if (_resultCode == Activity.RESULT_OK) {
ArrayList<String> _filePath = new ArrayList<>();
if (_data != null) {
if (_data.getClipData() != null) {
for (int _index = 0; _index < _data.getClipData().getItemCount(); _index++) {
ClipData.Item _item = _data.getClipData().getItemAt(_index);
_filePath.add(FileUtil.convertUriToFilePath(getApplicationContext(), _item.getUri()));
}
} else {
_filePath.add(FileUtil.convertUriToFilePath(getApplicationContext(), _data.getData()));
}
}
image = _filePath.get((int) (0));
} else {
}
break;
default:
break;
}
}
#Override
public void onDestroy() {
super.onDestroy();
try {
File fi = new File(Environment.getExternalStorageDirectory(), "saved");
if (!fi.exists()) {
fi.mkdirs();
}
File gpxfile = new File(fi, "saved.txt");
FileWriter writer = new FileWriter(gpxfile);
writer.append(url);
writer.flush();
writer.close();
} catch (IOException ee) {
ee.printStackTrace();
}
upload.PauseUploading();
startService(new Intent(this, UploadService.class));
startService(new Intent(getApplicationContext(), UploadSaveed.class));
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
UploadService
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
import com.google.android.gms.tasks.Task;
import com.google.firebase.storage.UploadTask;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class UploadService extends Service {
public static final String TAG = "UploadService";
private UploadSaveed upload;
#Nullable
#Override
public IBinder onBind(Intent i) {
return null;
}
#Override
public int onStartCommand(Intent i, int flags, int startId) {
upload = new UploadSaveed(getApplicationContext());
upload.setUploadListener(new UploadSaveed.UploadSavedListener() {
#Override
public void onFailureListener(Exception e) {
simpleNotifaction(1, "Upload Faild", "Upload Faild !");
try {
File fi = new File(Environment.getExternalStorageDirectory(), "saved");
if (!fi.exists()) {
fi.mkdirs();
}
File gpxfile = new File(fi, "errors.txt");
FileWriter writer = new FileWriter(gpxfile);
writer.append(e.toString());
writer.flush();
writer.close();
} catch (IOException ee) {
ee.printStackTrace();
}
}
#Override
public void onProgressListener(UploadTask.TaskSnapshot task) {
double progress = (100 * task.getBytesTransferred()) / task.getTotalByteCount();
notiProgress(1, "Uploading", "Your file is Uploading..", progress);
}
#Override
public void onPausedListener(UploadTask.TaskSnapshot task) {
SketchwareUtil.showMessage(getApplicationContext(), "your uploading is paused");
}
#Override
public void onSuccessListener(UploadTask.TaskSnapshot task) {
Task<Uri> taskk = task.getStorage().getDownloadUrl();
while (!taskk.isSuccessful())
;
simpleNotifaction(1, "Uploaded", "Url: " + taskk.getResult().toString());
stopSelf();
}
});
upload.UploadFormUrl(upload.getUploadUrl2());
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent i) {
startService(new Intent(this, UploadService.class));
super.onTaskRemoved(i);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
private void notiProgress(final double _id, final String _title, final String _text, final double _progress) {
final Context context = getApplicationContext();
android.app.NotificationManager notificationManager = (android.app.NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
androidx.core.app.NotificationCompat.Builder builder;
int notificationId = (int) _id;
String channelId = "channel-01";
String channelName = "Channel Name";
int importance = android.app.NotificationManager.IMPORTANCE_HIGH;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
android.app.NotificationChannel mChannel = new android.app.NotificationChannel(channelId, channelName,
importance);
notificationManager.createNotificationChannel(mChannel);
}
androidx.core.app.NotificationCompat.Builder mBuilder = new androidx.core.app.NotificationCompat.Builder(
context, channelId).setSmallIcon(android.R.drawable.stat_sys_upload).setTicker("")
.setContentTitle(_title).setContentText(_text).setProgress((int) 100, (int) _progress, false);
notificationManager.notify(notificationId, mBuilder.build());
}
private void simpleNotifaction(int id2, String title, String description) {
androidx.core.app.NotificationCompat.Builder builder = new androidx.core.app.NotificationCompat.Builder(this,
"channel-01")
.setSmallIcon(android.R.drawable.stat_sys_upload_done)
.setSound(android.media.RingtoneManager
.getDefaultUri(android.media.RingtoneManager.TYPE_NOTIFICATION))
.setContentTitle(title).setContentText(description)
.setPriority(androidx.core.app.NotificationCompat.PRIORITY_MAX).setAutoCancel(true);
androidx.core.app.NotificationManagerCompat notificationManager = androidx.core.app.NotificationManagerCompat
.from(this);
notificationManager.notify(id2, builder.build());
}
}
UploadSaveed
import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileWriter;
import java.util.List;
import java.util.Scanner;
public class UploadSaveed extends Service {
public static final String TAG = "UploadSaveed";
private FirebaseApp app;
private StorageReference storagee, path;
private UploadTask path2;
private List<UploadTask> tasks;
private String urll;
#Nullable
#Override
public IBinder onBind(Intent i) {
return null;
}
#Override
public int onStartCommand(Intent i, int flags, int startId) {
return START_STICKY;
}
public interface UploadSavedListener {
void onProgressListener(#NonNull UploadTask.TaskSnapshot task);
void onFailureListener(#NonNull Exception e);
void onSuccessListener(#NonNull UploadTask.TaskSnapshot task);
void onPausedListener(#NonNull UploadTask.TaskSnapshot task);
}
private UploadSavedListener listener;
public void setUploadListener(UploadSavedListener listener) {
this.listener = listener;
}
public UploadSaveed() {
}
public UploadSaveed(Context c) {
FirebaseOptions options = new FirebaseOptions.Builder()
.setApplicationId("1:982483603219:android:ce7ef5f660652cdca054e6")
.setApiKey("AIzaSyAhffAnCI7dG0d3NucUAjPM6oWaX6mVSHk")
.setDatabaseUrl("trav-chat-2-default-rtdb.firebaseio.com").setStorageBucket("trav-chat-2.appspot.com")
.build();
try {
FirebaseApp.initializeApp(c, options, "firebasedb");
app = FirebaseApp.getInstance("firebasedb");
} catch (Exception e) {
e.printStackTrace();
FirebaseApp.initializeApp(c, options);
app = FirebaseApp.getInstance("firebasedb");
}
try {
File fi = new File(Environment.getExternalStorageDirectory(), "saved");
if (!fi.exists()) {
fi.mkdirs();
}
File gpxfile = new File(fi, "ssaved.txt");
FileWriter writer = new FileWriter(gpxfile);
writer.append(app.toString());
writer.flush();
writer.close();
} catch (IOException ee) {
ee.printStackTrace();
}
}
public void UploadFile(String file) {
Uri file2 = Uri.parse(file);
Uri file3 = Uri.fromFile(new File(file));
storagee = FirebaseStorage.getInstance(app).getReference();
path = storagee.child("test image").child(file2.getLastPathSegment());
path2 = path.putFile(file3);
if (listener != null) {
path2.addOnFailureListener((e) -> {
listener.onFailureListener(e);
}).addOnPausedListener((task) -> {
listener.onPausedListener(task);
}).addOnProgressListener((task) -> {
listener.onProgressListener(task);
}).addOnSuccessListener((task) -> {
listener.onSuccessListener(task);
});
} else if (listener == null) {
throw new IllegalArgumentException("listener cannot be null");
}
}
/*
public void UploadFormUrl(String url) {
storagee = FirebaseStorage.getInstance(app).getReferenceFromUrl(url);
tasks = storagee.getActiveUploadTasks();
if (tasks.size() > 0) {
if (listener != null) {
path2 = tasks.get(0);
ResumeUploading();
SketchwareUtil.showMessage(this, "lol");
path2.addOnFailureListener((e) -> {
listener.onFailureListener(e);
}).addOnPausedListener((task) -> {
listener.onPausedListener(task);
}).addOnProgressListener((task) -> {
listener.onProgressListener(task);
}).addOnSuccessListener((task) -> {
listener.onSuccessListener(task);
});
} else {
throw new IllegalArgumentException("listener cannot be null");
}
} else {
throw new IllegalArgumentException("tasks cannot be equal 0 or less");
}
}
*/
public String getUploadUrl() {
if (path != null) {
return path.toString();
} else if (storagee != null) {
return storagee.toString();
} else {
throw new IllegalArgumentException("Storage Reference is null");
}
}
public void CancelUploading() {
path2.cancel();
}
public void PauseUploading() {
path2.pause();
}
public void ResumeUploading() {
path2.resume();
}
public String getUploadUrl2() {
urll = FileUtil.readFile(Environment.getExternalStorageDirectory().toString() + "/saved/saved.txt");
return urll;
}
#Override
public void onTaskRemoved(Intent i) {
startService(new Intent(this, UploadSaveed.class));
super.onTaskRemoved(i);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
}
Try to use intent
Try this code:
val intent = Intent(this, Main2Activity::class.java)
startActivity(intent)
Related
Video player is not buffering and the controller always false of isBuffering property
_controller.value.isBuffering
when i seek to a place i passed it re-download the video again .
I've tried to use other plugins but all of them depend on video_player under the hood
how to solve this issue ?
Replace this code with the code inside VideoPlayer.java file which is located inside video_player package. Then it will work
Link to file in github
package io.flutter.plugins.videoplayer;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_OFF;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.view.Surface;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Player.EventListener;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import io.flutter.plugin.common.EventChannel;
import io.flutter.view.TextureRegistry;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
final class VideoPlayer {
private static final String FORMAT_SS = "ss";
private static final String FORMAT_DASH = "dash";
private static final String FORMAT_HLS = "hls";
private static final String FORMAT_OTHER = "other";
private SimpleExoPlayer exoPlayer;
private Surface surface;
private final TextureRegistry.SurfaceTextureEntry textureEntry;
private QueuingEventSink eventSink = new QueuingEventSink();
private final EventChannel eventChannel;
private boolean isInitialized = false;
VideoPlayer(
Context context,
EventChannel eventChannel,
TextureRegistry.SurfaceTextureEntry textureEntry,
String dataSource,
String formatHint) {
this.eventChannel = eventChannel;
this.textureEntry = textureEntry;
TrackSelector trackSelector = new DefaultTrackSelector();
exoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector);
Uri uri = Uri.parse(dataSource);
DataSource.Factory dataSourceFactory;
if (isHTTP(uri)) {
dataSourceFactory =
new DefaultHttpDataSourceFactory(
"ExoPlayer",
null,
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
true);
} else {
dataSourceFactory = new DefaultDataSourceFactory(context, "ExoPlayer");
}
MediaSource mediaSource = buildMediaSource(uri, dataSourceFactory, formatHint, context);
exoPlayer.prepare(mediaSource);
setupVideoPlayer(eventChannel, textureEntry);
}
private static boolean isHTTP(Uri uri) {
if (uri == null || uri.getScheme() == null) {
return false;
}
String scheme = uri.getScheme();
return scheme.equals("http") || scheme.equals("https");
}
private MediaSource buildMediaSource(
Uri uri, DataSource.Factory mediaDataSourceFactory, String formatHint, Context context) {
int type;
if (formatHint == null) {
type = Util.inferContentType(uri.getLastPathSegment());
} else {
switch (formatHint) {
case FORMAT_SS:
type = C.TYPE_SS;
break;
case FORMAT_DASH:
type = C.TYPE_DASH;
break;
case FORMAT_HLS:
type = C.TYPE_HLS;
break;
case FORMAT_OTHER:
type = C.TYPE_OTHER;
break;
default:
type = -1;
break;
}
}
switch (type) {
case C.TYPE_SS:
return new SsMediaSource.Factory(
new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
new DefaultDataSourceFactory(context, null, mediaDataSourceFactory))
.createMediaSource(uri);
case C.TYPE_DASH:
return new DashMediaSource.Factory(
new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
new DefaultDataSourceFactory(context, null, mediaDataSourceFactory))
.createMediaSource(uri);
case C.TYPE_HLS:
return new HlsMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
case C.TYPE_OTHER:
return new ExtractorMediaSource.Factory(mediaDataSourceFactory)
.setExtractorsFactory(new DefaultExtractorsFactory())
.createMediaSource(uri);
default:
{
throw new IllegalStateException("Unsupported type: " + type);
}
}
}
private void setupVideoPlayer(
EventChannel eventChannel, TextureRegistry.SurfaceTextureEntry textureEntry) {
eventChannel.setStreamHandler(
new EventChannel.StreamHandler() {
#Override
public void onListen(Object o, EventChannel.EventSink sink) {
eventSink.setDelegate(sink);
}
#Override
public void onCancel(Object o) {
eventSink.setDelegate(null);
}
});
surface = new Surface(textureEntry.surfaceTexture());
exoPlayer.setVideoSurface(surface);
setAudioAttributes(exoPlayer);
exoPlayer.addListener(
new EventListener() {
#Override
public void onPlayerStateChanged(final boolean playWhenReady, final int playbackState) {
if (playbackState == Player.STATE_BUFFERING) {
sendBufferingUpdate();
Map<String, Object> event = new HashMap<>();
event.put("event", "bufferingStart");
eventSink.success(event);
} else if (playbackState == Player.STATE_READY) {
if (isInitialized) {
Map<String, Object> event = new HashMap<>();
event.put("event", "bufferingEnd");
eventSink.success(event);
} else {
isInitialized = true;
sendInitialized();
}
} else if (playbackState == Player.STATE_ENDED) {
Map<String, Object> event = new HashMap<>();
event.put("event", "completed");
eventSink.success(event);
}
}
#Override
public void onPlayerError(final ExoPlaybackException error) {
if (eventSink != null) {
eventSink.error("VideoError", "Video player had error " + error, null);
}
}
});
}
void sendBufferingUpdate() {
Map<String, Object> event = new HashMap<>();
event.put("event", "bufferingUpdate");
List<? extends Number> range = Arrays.asList(0, exoPlayer.getBufferedPosition());
// iOS supports a list of buffered ranges, so here is a list with a single range.
event.put("values", Collections.singletonList(range));
eventSink.success(event);
}
#SuppressWarnings("deprecation")
private static void setAudioAttributes(SimpleExoPlayer exoPlayer) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
exoPlayer.setAudioAttributes(
new AudioAttributes.Builder().setContentType(C.CONTENT_TYPE_MOVIE).build());
} else {
exoPlayer.setAudioStreamType(C.STREAM_TYPE_MUSIC);
}
}
void play() {
exoPlayer.setPlayWhenReady(true);
}
void pause() {
exoPlayer.setPlayWhenReady(false);
}
void setLooping(boolean value) {
exoPlayer.setRepeatMode(value ? REPEAT_MODE_ALL : REPEAT_MODE_OFF);
}
void setVolume(double value) {
float bracketedValue = (float) Math.max(0.0, Math.min(1.0, value));
exoPlayer.setVolume(bracketedValue);
}
void seekTo(int location) {
exoPlayer.seekTo(location);
}
long getPosition() {
return exoPlayer.getCurrentPosition();
}
#SuppressWarnings("SuspiciousNameCombination")
private void sendInitialized() {
if (isInitialized) {
Map<String, Object> event = new HashMap<>();
event.put("event", "initialized");
event.put("duration", exoPlayer.getDuration());
if (exoPlayer.getVideoFormat() != null) {
Format videoFormat = exoPlayer.getVideoFormat();
int width = videoFormat.width;
int height = videoFormat.height;
int rotationDegrees = videoFormat.rotationDegrees;
// Switch the width/height if video was taken in portrait mode
if (rotationDegrees == 90 || rotationDegrees == 270) {
width = exoPlayer.getVideoFormat().height;
height = exoPlayer.getVideoFormat().width;
}
event.put("width", width);
event.put("height", height);
}
eventSink.success(event);
}
}
void dispose() {
if (isInitialized) {
exoPlayer.stop();
}
textureEntry.release();
eventChannel.setStreamHandler(null);
if (surface != null) {
surface.release();
}
if (exoPlayer != null) {
exoPlayer.release();
}
}
}
I am looking to list the friends who are Facebook contacts and also have the app. It has shown a couple of times, but usually doesn't work.
I have no idea why. When I run the debugger, it says that I have a NullPointerException error on the following line:
friendslist = new JSONArray(jsondata);
I have tried a lot to work this out, so if you can let me know where my code goes wrong, I'll be very grateful.
I have included important pages below:
LoginActivity:
package com.phinder.phinder;
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.HttpMethod;
import com.facebook.appevents.AppEventsLogger;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import com.phinder.phinder.utils.ApiServices;
import com.phinder.phinder.utils.Constants;
import com.phinder.phinder.utils.MyLinks;
import org.json.JSONObject;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.GraphRequest;
import com.facebook.GraphRequestAsyncTask;
import com.facebook.GraphResponse;
import com.facebook.HttpMethod;
import com.facebook.appevents.AppEventsLogger;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Arrays;
public class LoginActivity extends AppCompatActivity /*implements View.OnClickListener*/ {
private final int REQUEST_READ_WRITE_PERMISSION = 3, REQUEST_CAMERA_PERMISSION = 4;
CallbackManager callbackManager;
AccessToken accessToken;
Retrofit retrofit;
ApiServices apiServices;
AppCompatActivity activity;
SharedPreferences.Editor editor;
LoginButton loginButton;
Toolbar toolbar;
private String profileUri = "", id = "", name = "", email = "";
private Constants constants;
private MyLinks myLinks;
private ProgressDialog progressDialog;
private boolean isReadWritePermitted = false, isCameraPermitted = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
facebookSDKInitialize();
setContentView(R.layout.activity_login);
Constants.loginSharedPreferences = getSharedPreferences(Constants.LoginPref, MODE_PRIVATE);
activity = LoginActivity.this;
myLinks = new MyLinks(activity);
constants = new Constants();
editor = Constants.loginSharedPreferences.edit();
toolbar = (Toolbar) findViewById(R.id.toolbar_activity_login);
setSupportActionBar(toolbar);
printKeyHash();
List<String> permission = new ArrayList<String>();
permission.add("email");
permission.add("public_profile");
permission.add("user_location");
permission.add("user_birthday");
permission.add("user_friends");
progressDialog = new ProgressDialog(activity);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(myLinks.DEFAULT_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
apiServices = retrofit.create(ApiServices.class);
loginButton = (LoginButton) findViewById(R.id.login_button);
loginButton.setReadPermissions(permission);
getLoginDetails(loginButton);
}
private void requestPermission() {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
isReadWritePermitted = true;
} else {
// Show rationale and request permission.
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_READ_WRITE_PERMISSION);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_READ_WRITE_PERMISSION) {
if (permissions.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
isReadWritePermitted = true;
getLoginDetails(loginButton);
} else {
isReadWritePermitted = false;
}
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void facebookSDKInitialize() {
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
}
private void getLoginDetails(final LoginButton loginButton) {
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
loginButton.setVisibility(View.INVISIBLE);
progressDialog.show();
Log.d("msg", "Facebook");
accessToken = AccessToken.getCurrentAccessToken();
SharedPreferences.Editor editor = Constants.loginSharedPreferences
.edit();
editor.putString(constants.LoginId, accessToken.getUserId());
editor.apply();
Log.d("msg", "fbid : " + accessToken.getUserId());
onSuccessFullLogIn(accessToken);
GraphRequestAsyncTask graphRequestAsyncTask = new GraphRequest(
loginResult.getAccessToken(),
//AccessToken.getCurrentAccessToken(),
"/me/friends",
null,
HttpMethod.GET,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
try {
JSONArray rawName = response.getJSONObject().getJSONArray("data");
intent.putExtra("jsondata", rawName.toString());
startActivity(intent);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
).executeAsync();
}
#Override
public void onCancel() {
}
#Override
public void onError(FacebookException error) {
}
});
}
public void onSuccessFullLogIn(final AccessToken accessToken) {
Bundle params = new Bundle();
params.putString("fields", "id,name,location,email,picture.type(large)");
new GraphRequest(accessToken, "me", params, HttpMethod.GET, new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
if (response != null) {
try {
Log.d("msg", "Fb data1 : " + response.toString() + "");
JSONObject data = response.getJSONObject();
Log.d("msg", "Fb data : " + data.toString() + "");
SharedPreferences.Editor editor = Constants.loginSharedPreferences
.edit();
if (data.has("picture")) {
profileUri = data.getJSONObject("picture")
.getJSONObject("data")
.getString("url");
if (profileUri.startsWith("http://")
|| profileUri
.startsWith("https://")) {
profileUri = profileUri.replace(
"http://", "").trim();
profileUri = profileUri.replace(
"https://", "").trim();
}
editor.putString(constants.LoginImage, profileUri);
}
if (data.has("name")) {
editor.putString(constants.LoginName, data.getString("name"));
}
//if (data.has("email")) {
// Log.d("email", data.getString("email"));
// editor.putString(constants.LoginEmail, data.getString("email"));
//}
//if (data.has("location")) {
// editor.putString("city", data
// .getJSONObject("location")
// .getString("name"));
//}
editor.putBoolean(constants.LoginStatus, true);
editor.apply();
LoginManager.getInstance().logOut();
} catch (Exception e) {
e.printStackTrace();
} finally {
finish();
startActivity(new Intent(getApplicationContext(), MainActivity.class));
progressDialog.dismiss();
// final ProgressDialog progressDialog = new ProgressDialog(LoginActivity.this);
// progressDialog.show();
// Call<ResponseBody> call = apiServices.socialCall(Constants.loginSharedPreferences.getString(constants.LoginName, ""),
// Constants.loginSharedPreferences.getString(constants.LoginId, ""),
// Constants.loginSharedPreferences.getString(constants.LoginEmail, ""),
// Constants.loginSharedPreferences.getString(constants.LoginImage, "")
// );
//
// call.enqueue(new Callback<ResponseBody>() {
// #Override
// public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
// try {
//
// String result = response.body().string();
//
// Log.d("msg", "Result : " + result);
//
//
// JSONObject jsonObject = new JSONObject(result);
//// progressDialog.dismiss();
//
//
// if (jsonObject != null && jsonObject.length() > 0) {
//
// JSONArray jsonArray = jsonObject.getJSONArray("response");
//
// Log.d("msg", "Json : " + jsonArray.toString());
//
// if (jsonArray != null && jsonArray.length() > 0) {
//
// for (int i = 0; i < jsonArray.length(); i++) {
//
// JSONObject jsonObject1 = jsonArray.getJSONObject(i);
//
// String status = jsonObject1.getString("status");
// String id = jsonObject1.getString("id");
//
// SharedPreferences.Editor editor = Constants.loginSharedPreferences.edit();
// editor.putString(constants.UserId, id);
// editor.apply();
//
// if (status.equals("one") || status.equals("zero")) {
// startActivity(new Intent(activity, MainActivity.class));
// finish();
//
// } else {
// Toast.makeText(activity, "Invalid login", Toast.LENGTH_LONG).show();
// }
// }
// }
// }
//
// } catch (IOException e) {
// e.getStackTrace();
//
// Log.d("msg", "IO " + e.getMessage());
// progressDialog.dismiss();
// } catch (JSONException e) {
//
// e.printStackTrace();
// Log.d("msg", "JSON " + e.getMessage());
// progressDialog.dismiss();
// }
// }
//
// #Override
// public void onFailure(Call<ResponseBody> call, Throwable t) {
// Log.d("msg", "JSON " + t.getMessage());
//
// progressDialog.dismiss();
// }
// });
}
}
}
}).executeAsync();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
// Log.d("data",data.toString());
}
#Override
protected void onResume() {
super.onResume();
AppEventsLogger.activateApp(LoginActivity.this, "369622066719726");
}
#Override
protected void onPause() {
super.onPause();
AppEventsLogger.deactivateApp(LoginActivity.this, "369622066719726");
}
public String printKeyHash() {
PackageInfo packageInfo;
String key = null;
try {
//getting application package name, as defined in manifest
String packageName = getApplicationContext().getPackageName();
//Retriving package info
packageInfo = getPackageManager().getPackageInfo(packageName,
PackageManager.GET_SIGNATURES);
Log.d("Package Name=", getApplicationContext().getPackageName());
for (Signature signature : packageInfo.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
key = new String(Base64.encode(md.digest(), 0));
// String key = new String(Base64.encodeBytes(md.digest()));
Log.d("Key Hash=", key);
// ST4ot689mPBUodJzQxMIutXIkKw=
}
} catch (PackageManager.NameNotFoundException e1) {
Log.e("Name not found", e1.toString());
} catch (NoSuchAlgorithmException e) {
Log.d("No such an algorithm", e.toString());
} catch (Exception e) {
Log.d("Exception", e.toString());
}
return key;
}
}
MainActivity:
package com.phinder.phinder;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.json.JSONArray;
import org.json.JSONException;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ImageView imageView_picture_profile;
TextView textview_nameprofile,textview_emailprofile;
public com.phinder.phinder.utils.Constants constants;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// User Information
constants = new com.phinder.phinder.utils.Constants();
imageView_picture_profile = (ImageView)findViewById(R.id.imageView_picture_profile);
//textview_emailprofile = (TextView) findViewById(R.id.textview_emailprofile);
textview_nameprofile = (TextView)findViewById(R.id.textview_nameprofile);
//textview_emailprofile.setText(constants.loginSharedPreferences.getString(constants.LoginEmail, ""));
textview_nameprofile.setText(constants.loginSharedPreferences.getString(constants.LoginName, ""));
try {
Glide.with(getApplicationContext())
.load("http://" + constants.loginSharedPreferences.getString(constants.LoginImage, ""))
.placeholder(R.mipmap.ic_launcher)
.thumbnail(.1F)
.error(R.mipmap.ic_launcher)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(imageView_picture_profile);
} catch (Exception e) {
e.getStackTrace();
Log.d("msg", "Photo " + e.getMessage());
}
//ListView Facebook Friends
Intent intent = getIntent();
String jsondata = intent.getStringExtra("jsondata");
JSONArray friendslist;
ArrayList<String> friends = new ArrayList<String>();
try {
friendslist = new JSONArray(jsondata);
for (int l=0; l < friendslist.length(); l++) {
friends.add(friendslist.getJSONObject(l).getString("name"));
}
} catch (JSONException e) {
e.printStackTrace();
}
ArrayAdapter adapter = new ArrayAdapter<String>(this, R.layout.activity_listview, friends); // simple textview for list item
ListView listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
}
}
Okay guys, I was playing about with it and I found out what the issue was, finally!
I had a duplicate token access request in LoginActivity.java which was causing this issue.
onSuccessFullLogIn(accessToken);
when I commented this out, it worked perfectly
I know I'm answering my own question here, but I noticed this issue is around the internet a lot, with no real answer, so I hope it's useful for some people!
I have put a GWT-CellTree in a DataGrid. It works except for one thing: When clicking on the tree-expand-icon, nothing happens. I have tried to minimize the
code needed to reproduce the problem...
How can this be fixed ?
best regards, Magnus
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.SimpleLayoutPanel;
public class HelloWorld implements EntryPoint {
public void onModuleLoad() {
DataGrid grid= (DataGrid) new NodesGrid().getTable();
grid.setWidth("100%");
SimpleLayoutPanel slp = new SimpleLayoutPanel();
slp.add(grid);
RootLayoutPanel.get().add(slp);
}
}
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.cell.client.ClickableTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.dom.client.Style;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.text.shared.AbstractSafeHtmlRenderer;
import com.google.gwt.text.shared.SafeHtmlRenderer;
import com.google.gwt.user.cellview.client.*;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.view.client.ListDataProvider;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
public class NodesGrid {
private AbstractCellTable<Node> table = new DataGrid<>();
private Column nameColumn;
private Column<Node, String> showBlocksColumn;
private final Set<Integer> showBlocks = new HashSet<>();
public Column getNameColumn() {
return nameColumn;
}
public AbstractCellTable<Node> getTable() {
return table;
}
public NodesGrid() {
table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
table.setWidth("100%");
CustomCellTableBuilder c = new CustomCellTableBuilder(this, table);
table.setTableBuilder(c);
Node nodes = new Node();
nodes.setName("hello");
nodes.setId(123);
Node n2 = new Node();
n2.setName("testing");
nodes.getBlocks().add(n2);
ListDataProvider<Node> dataProvider = new ListDataProvider<>();
dataProvider.addDataDisplay(table);
List<Node> list = dataProvider.getList();
list.add(nodes);
addShowBlocks();
nameColumn = getSorter(list, "Name", Comparator.comparing(Node::getName), Node::getName);
}
private Column getSorter(List<Node> list,
String name,
Comparator<Node> cmp,
Function<Node, String> supplier) {
TextColumn<Node> column = new TextColumn<Node>() {
#Override
public String getValue(Node object) {
return supplier.apply(object);
}
};
table.addColumn(column, name);
column.setSortable(true);
ColumnSortEvent.ListHandler<Node> columnSortHandler = new ColumnSortEvent.ListHandler<>(list);
columnSortHandler.setComparator(column, cmp);
table.addColumnSortHandler(columnSortHandler);
table.getColumnSortList().push(column);
return column;
}
public Column<Node, String> getShowBlocksColumn() {
return showBlocksColumn;
}
public Set<Integer> getShowBlocks() {
return showBlocks;
}
void addShowBlocks() {
SafeHtmlRenderer<String> anchorRenderer = new AbstractSafeHtmlRenderer<String>() {
#Override
public SafeHtml render(String object) {
SafeHtmlBuilder sb = new SafeHtmlBuilder();
sb.appendHtmlConstant("(<a href=\"javascript:;\">").appendEscaped(object)
.appendHtmlConstant("</a>)");
return sb.toSafeHtml();
}
};
showBlocksColumn = new Column<Node, String>(new ClickableTextCell(anchorRenderer)) {
#Override
public String getValue(Node node) {
if (showBlocks.contains(node.getId())) {
return "hide blocks";
} else {
return "show blocks";
}
}
};
showBlocksColumn.setFieldUpdater(new FieldUpdater<Node, String>() {
#Override
public void update(int index, Node node, String value) {
if (showBlocks.contains(node.getId())) {
showBlocks.remove(node.getId());
} else {
showBlocks.add(node.getId());
}
table.redrawRow(index);
}
});
table.addColumn(showBlocksColumn);
table.setColumnWidth(0, 10, Style.Unit.EM);
}
}
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TreeNode;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.view.client.TreeViewModel;
import java.util.ArrayList;
import java.util.List;
public class NodesTree {
private CellTree tree;
public NodesTree(Node node) {
TreeViewModel model = new CustomTreeModel(node);
tree = new CellTree(model, null);
tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
TreeNode rootNode = tree.getRootTreeNode();
openAll(rootNode);
}
private static class TopLevel {
private final String name;
private List<Node> blocks = new ArrayList<>();
public TopLevel(String name) {
this.name = name;
}
public TopLevel(String name, List<Node> blocks) {
this.name = name;
this.blocks = blocks;
}
public String getName() {
return name;
}
public List<Node> getBlocks() {
return blocks;
}
}
private static class CustomTreeModel implements TreeViewModel {
private final List<TopLevel> topLevels;
private final SingleSelectionModel<String> selectionModel
= new SingleSelectionModel<>();
public CustomTreeModel(Node node) {
topLevels = new ArrayList<>();
{
TopLevel blocksNode = new TopLevel("Blocks", new ArrayList(node.getBlocks()));
topLevels.add(blocksNode);
}
{
TopLevel outgoing = new TopLevel("Outgoing");
topLevels.add(outgoing);
}
{
TopLevel incoming = new TopLevel("Incoming");
topLevels.add(incoming);
}
}
public <T> NodeInfo<?> getNodeInfo(T value) {
if (value == null) {
// LEVEL 0.
ListDataProvider<TopLevel> dataProvider
= new ListDataProvider<>(
topLevels);
Cell<TopLevel> cell = new AbstractCell<TopLevel>() {
#Override
public void render(Context context, TopLevel value, SafeHtmlBuilder sb) {
sb.appendHtmlConstant(" ");
sb.appendEscaped(value.getName());
}
};
return new DefaultNodeInfo<>(dataProvider, cell);
} else if (value instanceof TopLevel) {
// LEVEL 1.
ListDataProvider<Node> dataProvider = new ListDataProvider<>(((TopLevel) value).getBlocks());
Cell<Node> cell = new AbstractCell<Node>() {
#Override
public void render(Context context, Node value, SafeHtmlBuilder sb) {
if (value != null) {
sb.appendHtmlConstant(" ");
sb.appendEscaped("(" + value.getName() + ")");
}
}
};
return new DefaultNodeInfo<>(dataProvider, cell);
} else if (value instanceof Node) {
// LEVEL 2 - LEAF.
String params = "test";
ArrayList<String> str = new ArrayList<>();
str.add(params);
ListDataProvider<String> dataProvider = new ListDataProvider<>(str);
return new DefaultNodeInfo<>(dataProvider, new TextCell(), selectionModel, null);
}
return null;
}
public boolean isLeaf(Object value) {
if (value instanceof String) {
return true;
}
return false;
}
}
private void openAll(TreeNode rootNode) {
if (rootNode == null) return;
for (int i = 0; i < rootNode.getChildCount(); i++) {
TreeNode node = rootNode.setChildOpen(i, true);
openAll(node);
}
}
public Widget getWidget() {
return tree;
}
}
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.dom.builder.shared.DivBuilder;
import com.google.gwt.dom.builder.shared.TableCellBuilder;
import com.google.gwt.dom.builder.shared.TableRowBuilder;
import com.google.gwt.dom.client.Style;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.cellview.client.AbstractCellTable;
import com.google.gwt.user.cellview.client.AbstractCellTableBuilder;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.view.client.SelectionModel;
public class CustomCellTableBuilder extends AbstractCellTableBuilder<Node> {
NodesGrid nodesGrid;
private final String rowStyle;
private final String selectedRowStyle;
private final String cellStyle;
private final String selectedCellStyle;
/**
* Construct a new table builder.
*
* #param cellTable the table this builder will build rows for
*/
public CustomCellTableBuilder(NodesGrid nodesGrid, AbstractCellTable<Node> cellTable) {
super(cellTable);
this.nodesGrid = nodesGrid;
AbstractCellTable.Style style = cellTable.getResources().style();
rowStyle = style.evenRow();
selectedRowStyle = " " + style.selectedRow();
cellStyle = style.cell() + " " + style.evenRowCell();
selectedCellStyle = " " + style.selectedRowCell();
}
#Override
protected void buildRowImpl(Node rowValue, int absRowIndex) {
// Calculate the row styles.
SelectionModel<? super Node> selectionModel = cellTable.getSelectionModel();
boolean isSelected =
(selectionModel == null || rowValue == null) ? false : selectionModel
.isSelected(rowValue);
StringBuilder trClasses = new StringBuilder(rowStyle);
if (isSelected) {
trClasses.append(selectedRowStyle);
}
String cellStyles = cellStyle;
if (isSelected) {
cellStyles += selectedCellStyle;
}
TableRowBuilder row = startRow();
row.className(trClasses.toString());
buildRow(row, rowValue, cellStyles, nodesGrid.getShowBlocksColumn());
buildRow(row, rowValue, cellStyles, nodesGrid.getNameColumn());
row.endTR();
if (nodesGrid.getShowBlocks().contains(rowValue.getId())) {
buildBlockRow(rowValue, cellStyles);
}
}
void buildRow(TableRowBuilder row, Node rowValue, String cellStyles, Column column) {
TableCellBuilder td = row.startTD();
td.className(cellStyles);
td.style().outlineStyle(Style.OutlineStyle.NONE).endStyle();
renderCell(td, createContext(0), column, rowValue);
td.endTD();
}
private void buildBlockRow(Node rowValue, String cellStyles) {
TableRowBuilder row = startRow();
buildCell(rowValue, cellStyles, row);
row.endTR();
}
private void buildCell(Node rowValue, String cellStyles, TableRowBuilder row) {
NodesTree hw = new NodesTree(rowValue);
TableCellBuilder td = row.startTD().colSpan(5);
td.className(cellStyles);
DivBuilder div = td.startDiv();
String t = hw.getWidget().getElement().getInnerHTML();
div.html(SafeHtmlUtils.fromTrustedString(t));
div.end();
td.endTD();
}
}
package com.raybased.gwt.configtool.client.grid;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class Node implements Serializable {
String name;
List<Node> blocks = new ArrayList<>();
String params;
int id;
public Node() {
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Node> getBlocks() {
return blocks;
}
}
I'm using an editable ListView containing Patterns.
The user can see and edit the regexs in the list, and I'd like to validate whether the regex is syntactically correct before committing the value (and give feedback like a red border to the user).
Is there a way to do so?
patternList.setCellFactory(TextFieldListCell.forListView(new StringConverter<Pattern>() {
#Override
public String toString(Pattern pattern) {
return pattern.toString();
}
#Override
public Pattern fromString(String string) {
try {
return Pattern.compile(string);
} catch (PatternSyntaxException e) {
return null;
}
}
}));
patternList.setOnEditCommit(e -> {
if (e.getNewValue() == null) {
// TODO pattern syntax error, prevent commit and stay in edit mode
} else {
patternList.getItems().set(e.getIndex(), e.getNewValue());
}
});
I would do this by creating a TableCell implementation. E.g.:
import java.util.function.Predicate;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.css.PseudoClass;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
public class ValidatingEditingCell<S> extends TableCell<S, String> {
private final TextField textField ;
private static final PseudoClass INVALID = PseudoClass.getPseudoClass("invalid");
private BooleanProperty valid = new SimpleBooleanProperty();
public ValidatingEditingCell(Predicate<String> validator) {
this.textField = new TextField();
valid.bind(Bindings.createBooleanBinding(() -> textField.getText() != null && validator.test(textField.getText()),
textField.textProperty()));
valid.addListener((obs, wasValid, isValid) -> {
pseudoClassStateChanged(INVALID, ! isValid);
});
pseudoClassStateChanged(INVALID, ! valid.get());
textField.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
if (e.getCode() == KeyCode.ENTER && valid.get()) {
commitEdit(textField.getText());
}
if (e.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
});
setGraphic(textField);
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setText(empty ? null : item);
textField.setText(empty ? null : item);
setContentDisplay(isEditing() ? ContentDisplay.GRAPHIC_ONLY : ContentDisplay.TEXT_ONLY);
}
#Override
public void cancelEdit() {
super.cancelEdit();
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
#Override
public void commitEdit(String newValue) {
super.commitEdit(newValue);
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
#Override
public void startEdit() {
super.startEdit();
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
textField.selectAll();
textField.requestFocus();
}
}
This takes a predicate as an argument; the predicate returns true for valid text and false for invalid text. It sets a CSS pseudoclass on the cell, so you can use CSS to style the text field (or cell itself, if needed).
Here's a simple example which validates three different columns differently:
import java.util.function.Function;
import java.util.function.Predicate;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ValidatingTableExample extends Application {
private static <S> TableColumn<S, String> column(String title, Function<S, StringProperty> property,
Predicate<String> validator) {
TableColumn<S, String> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
col.setCellFactory(tc -> new ValidatingEditingCell<>(validator));
col.setPrefWidth(150);
return col ;
}
#Override
public void start(Stage primaryStage) {
TableView<Address> table = new TableView<>();
table.setEditable(true);
table.getColumns().add(column("City", Address::cityProperty, s -> ! s.isEmpty()));
table.getColumns().add(column("State", Address::stateProperty, s -> s.length()==2));
table.getColumns().add(column("Zip", Address::zipProperty, s -> s.matches("\\d{5}")));
Button newAddress = new Button("Add");
newAddress.setOnAction(e -> {
table.getItems().add(new Address("City", "State", "Zip"));
});
Button debug = new Button("Debug");
debug.setOnAction(e ->
table.getItems().stream()
.map(address -> String.format("%s, %s %s", address.getCity(), address.getState(), address.getZip()))
.forEach(System.out::println));
HBox buttons = new HBox(5, newAddress, debug);
buttons.setAlignment(Pos.CENTER);
buttons.setPadding(new Insets(5));
BorderPane root = new BorderPane(table, null, null, buttons, null);
Scene scene = new Scene(root, 600, 600);
scene.getStylesheets().add(getClass().getResource("validating-cell.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
public static class Address {
private final StringProperty city = new SimpleStringProperty();
private final StringProperty state = new SimpleStringProperty();
private final StringProperty zip = new SimpleStringProperty();
public Address(String city, String state, String zip) {
setCity(city);
setState(state);
setZip(zip);
}
public final StringProperty cityProperty() {
return this.city;
}
public final String getCity() {
return this.cityProperty().get();
}
public final void setCity(final String city) {
this.cityProperty().set(city);
}
public final StringProperty stateProperty() {
return this.state;
}
public final String getState() {
return this.stateProperty().get();
}
public final void setState(final String state) {
this.stateProperty().set(state);
}
public final StringProperty zipProperty() {
return this.zip;
}
public final String getZip() {
return this.zipProperty().get();
}
public final void setZip(final String zip) {
this.zipProperty().set(zip);
}
}
public static void main(String[] args) {
launch(args);
}
}
and some sample CSS:
.table-cell:invalid .text-field {
-fx-focus-color: red ;
-fx-control-inner-background: #ffc0c0 ;
-fx-accent: red ;
}
I finally found a way, by overriding the commitEdit() method of TextFieldListCell:
patternList.setCellFactory(l -> new TextFieldListCell<Pattern>(new StringConverter<Pattern>() {
#Override
public String toString(Pattern pattern) {
return pattern.toString();
}
#Override
public Pattern fromString(String string) {
try {
return Pattern.compile(string);
} catch (PatternSyntaxException e) {
return null;
}
}
}) {
#Override
public void commitEdit(Pattern pattern) {
if (!isEditing()) return;
PseudoClass errorClass = PseudoClass.getPseudoClass("error");
pseudoClassStateChanged(errorClass, pattern == null);
if (pattern != null) {
super.commitEdit(pattern);
}
}
});
patternList.setOnEditCommit(e -> patternList.getItems().set(e.getIndex(), e.getNewValue()));
Is it possible to retrieve and log the request XML to a file at OutFaultInterceptor when I hit an error such as fail schema validation?
I have tried search the web but don't seems to be able to find much related to this.
Yest it is possible. I have wrote CxfOutInterceptor for getting XML of the message. Here is the code:
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.io.CacheAndWriteOutputStream;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.io.CachedOutputStreamCallback;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CxfOutInterceptor extends AbstractPhaseInterceptor<Message> {
private static final Logger LOGGER = LoggerFactory.getLogger(CxfInInterceptor.class);
public CxfOutInterceptor() {
super(Phase.PRE_STREAM);
}
public static final String SINGLE_KEY = CxfOutInterceptor.class.getName() + ".Processed";
private static final int LIMIT = 10 * 1024 * 1024;
#Override
public void handleFault(Message message) {
LOGGER.trace("handleFault");
try {
internalHandleMessage(message);
} catch (Throwable ex) {
LOGGER.error("Exception thrown by internalHandleMessage: ", ex);
} finally {
LOGGER.trace("handleFault - end");
}
}
#Override
public void handleMessage(Message message) throws Fault {
LOGGER.trace("handleMessage");
try {
if (onceOnly(message)) {
LOGGER.debug("handled message previously");
return;
}
internalHandleMessage(message);
} finally {
LOGGER.trace("handleMessage - end");
}
}
private class LogCallback implements CachedOutputStreamCallback {
private final Message message;
private final OutputStream origStream;
public LogCallback(final Message msg, final OutputStream os) {
this.message = msg;
this.origStream = os;
}
#Override
public void onFlush(CachedOutputStream cos) {
}
#Override
public void onClose(CachedOutputStream cos) {
StringBuilder requestBuilder = new StringBuilder();
String encoding = (String) message.get(Message.ENCODING);
try {
writePayload(requestBuilder, cos, encoding);
//requestBuilder - is your actuall body of the message.
} catch (IOException ex) {
LOGGER.trace("Unable to write output stream to StringBuilder:\n" + ex.toString());
}
try {
cos.lockOutputStream();
cos.resetOut(null, false);
} catch (Exception ex) {
LOGGER.info("Ignoring exception");
}
message.setContent(OutputStream.class, origStream);
}
}
private void internalHandleMessage(Message message) {
final OutputStream os = message.getContent(OutputStream.class);
final Writer writer = message.getContent(Writer.class);
if (os == null && writer == null) {
return;
}
if (os == null) {
message.setContent(Writer.class, writer);
} else {
final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os);
message.setContent(OutputStream.class, newOut);
newOut.registerCallback(new LogCallback(message, os));
}
}
private static boolean onceOnly(Message message) {
if (message.getExchange().containsKey(SINGLE_KEY)) {
return true;
} else {
message.getExchange().put(SINGLE_KEY, Boolean.TRUE);
return false;
}
}
private static void writePayload(StringBuilder builder, CachedOutputStream cos, String encoding)
throws IOException {
if (StringUtils.isEmpty(encoding)) {
cos.writeCacheTo(builder, LIMIT);
} else {
cos.writeCacheTo(builder, encoding, LIMIT);
}
}
}
You will get the XML of the message in onClose method. Refer to this comment: //requestBuilder - is your actuall XML of the message.