What changes do I need to make to the following code to get an m3u8 link to play?
I'm able to get regular MP4 videos to work, but not HLS. What would I need to do to make HLS links to work?
I would like to implement something like this, that allows for playback of different media sources. https://gist.github.com/navi25/7ab41931eb52bbcb693b5599e6955245#file-mediasourcebuilder-kt
public class VideoPlayerRecyclerView extends RecyclerView {
private static final String TAG = "VideoPlayerRecyclerView";
private enum VolumeState {ON, OFF};
// ui
private ImageView thumbnail, volumeControl;
private ProgressBar progressBar;
private View viewHolderParent;
private FrameLayout frameLayout;
private PlayerView videoSurfaceView;
private SimpleExoPlayer videoPlayer;
// vars
private ArrayList<MediaObject> mediaObjects = new ArrayList<>();
private int videoSurfaceDefaultHeight = 0;
private int screenDefaultHeight = 0;
private Context context;
private int playPosition = -1;
private boolean isVideoViewAdded;
private RequestManager requestManager;
// controlling playback state
private VolumeState volumeState;
public VideoPlayerRecyclerView(#NonNull Context context) {
super(context);
init(context);
}
public VideoPlayerRecyclerView(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
this.context = context.getApplicationContext();
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point point = new Point();
display.getSize(point);
videoSurfaceDefaultHeight = point.x;
screenDefaultHeight = point.y;
videoSurfaceView = new PlayerView(this.context);
videoSurfaceView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_ZOOM);
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector =
new DefaultTrackSelector(videoTrackSelectionFactory);
// 2. Create the player
videoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector);
// Bind the player to the view.
videoSurfaceView.setUseController(false);
videoSurfaceView.setPlayer(videoPlayer);
setVolumeControl(VolumeState.ON);
addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
Log.d(TAG, "onScrollStateChanged: called.");
if(thumbnail != null){ // show the old thumbnail
thumbnail.setVisibility(VISIBLE);
}
// There's a special case when the end of the list has been reached.
// Need to handle that with this bit of logic
if(!recyclerView.canScrollVertically(1)){
playVideo(true);
}
else{
playVideo(false);
}
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
addOnChildAttachStateChangeListener(new OnChildAttachStateChangeListener() {
#Override
public void onChildViewAttachedToWindow(View view) {
}
#Override
public void onChildViewDetachedFromWindow(View view) {
if (viewHolderParent != null && viewHolderParent.equals(view)) {
resetVideoView();
}
}
});
videoPlayer.addListener(new Player.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, #Nullable Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_BUFFERING:
Log.e(TAG, "onPlayerStateChanged: Buffering video.");
if (progressBar != null) {
progressBar.setVisibility(VISIBLE);
}
break;
case Player.STATE_ENDED:
Log.d(TAG, "onPlayerStateChanged: Video ended.");
videoPlayer.seekTo(0);
break;
case Player.STATE_IDLE:
break;
case Player.STATE_READY:
Log.e(TAG, "onPlayerStateChanged: Ready to play.");
if (progressBar != null) {
progressBar.setVisibility(GONE);
}
if(!isVideoViewAdded){
addVideoView();
}
break;
default:
break;
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
});
}
public void playVideo(boolean isEndOfList) {
int targetPosition;
if(!isEndOfList){
int startPosition = ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
int endPosition = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
// if there is more than 2 list-items on the screen, set the difference to be 1
if (endPosition - startPosition > 1) {
endPosition = startPosition + 1;
}
// something is wrong. return.
if (startPosition < 0 || endPosition < 0) {
return;
}
// if there is more than 1 list-item on the screen
if (startPosition != endPosition) {
int startPositionVideoHeight = getVisibleVideoSurfaceHeight(startPosition);
int endPositionVideoHeight = getVisibleVideoSurfaceHeight(endPosition);
targetPosition = startPositionVideoHeight > endPositionVideoHeight ? startPosition : endPosition;
}
else {
targetPosition = startPosition;
}
}
else{
targetPosition = mediaObjects.size() - 1;
}
Log.d(TAG, "playVideo: target position: " + targetPosition);
// video is already playing so return
if (targetPosition == playPosition) {
return;
}
// set the position of the list-item that is to be played
playPosition = targetPosition;
if (videoSurfaceView == null) {
return;
}
// remove any old surface views from previously playing videos
videoSurfaceView.setVisibility(INVISIBLE);
removeVideoView(videoSurfaceView);
int currentPosition = targetPosition - ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
View child = getChildAt(currentPosition);
if (child == null) {
return;
}
VideoPlayerViewHolder holder = (VideoPlayerViewHolder) child.getTag();
if (holder == null) {
playPosition = -1;
return;
}
thumbnail = holder.thumbnail;
progressBar = holder.progressBar;
volumeControl = holder.volumeControl;
viewHolderParent = holder.itemView;
requestManager = holder.requestManager;
frameLayout = holder.itemView.findViewById(R.id.media_container);
videoSurfaceView.setPlayer(videoPlayer);
viewHolderParent.setOnClickListener(videoViewClickListener);
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(
context, Util.getUserAgent(context, "RecyclerView VideoPlayer"));
String mediaUrl = mediaObjects.get(targetPosition).getMedia_url();
if (mediaUrl != null) {
MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(mediaUrl));
videoPlayer.prepare(videoSource);
videoPlayer.setPlayWhenReady(true);
}
}
private OnClickListener videoViewClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
toggleVolume();
}
};
/**
* Returns the visible region of the video surface on the screen.
* if some is cut off, it will return less than the #videoSurfaceDefaultHeight
* #param playPosition
* #return
*/
private int getVisibleVideoSurfaceHeight(int playPosition) {
int at = playPosition - ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
Log.d(TAG, "getVisibleVideoSurfaceHeight: at: " + at);
View child = getChildAt(at);
if (child == null) {
return 0;
}
int[] location = new int[2];
child.getLocationInWindow(location);
if (location[1] < 0) {
return location[1] + videoSurfaceDefaultHeight;
} else {
return screenDefaultHeight - location[1];
}
}
// Remove the old player
private void removeVideoView(PlayerView videoView) {
ViewGroup parent = (ViewGroup) videoView.getParent();
if (parent == null) {
return;
}
int index = parent.indexOfChild(videoView);
if (index >= 0) {
parent.removeViewAt(index);
isVideoViewAdded = false;
viewHolderParent.setOnClickListener(null);
}
}
private void addVideoView(){
frameLayout.addView(videoSurfaceView);
isVideoViewAdded = true;
videoSurfaceView.requestFocus();
videoSurfaceView.setVisibility(VISIBLE);
videoSurfaceView.setAlpha(1);
thumbnail.setVisibility(GONE);
}
private void resetVideoView(){
if(isVideoViewAdded){
removeVideoView(videoSurfaceView);
playPosition = -1;
videoSurfaceView.setVisibility(INVISIBLE);
thumbnail.setVisibility(VISIBLE);
}
}
public void releasePlayer() {
if (videoPlayer != null) {
videoPlayer.release();
videoPlayer = null;
}
viewHolderParent = null;
}
private void toggleVolume() {
if (videoPlayer != null) {
if (volumeState == VolumeState.OFF) {
Log.d(TAG, "togglePlaybackState: enabling volume.");
setVolumeControl(VolumeState.ON);
} else if(volumeState == VolumeState.ON) {
Log.d(TAG, "togglePlaybackState: disabling volume.");
setVolumeControl(VolumeState.OFF);
}
}
}
private void setVolumeControl(VolumeState state){
volumeState = state;
if(state == VolumeState.OFF){
videoPlayer.setVolume(0f);
animateVolumeControl();
}
else if(state == VolumeState.ON){
videoPlayer.setVolume(1f);
animateVolumeControl();
}
}
private void animateVolumeControl(){
if(volumeControl != null){
volumeControl.bringToFront();
if(volumeState == VolumeState.OFF){
requestManager.load(R.drawable.ic_volume_off_grey_24dp)
.into(volumeControl);
}
else if(volumeState == VolumeState.ON){
requestManager.load(R.drawable.ic_volume_up_grey_24dp)
.into(volumeControl);
}
volumeControl.animate().cancel();
volumeControl.setAlpha(1f);
volumeControl.animate()
.alpha(0f)
.setDuration(600).setStartDelay(1000);
}
}
public void setMediaObjects(ArrayList<MediaObject> mediaObjects){
this.mediaObjects = mediaObjects;
}
}
You need to use HlsMediaSource instead of the default MediaSource for HLS.
Media sources
Related
I am facing the issue with my Recycler view while placing Admob ads after every 5 items. First ads display after 5 items but when swept up/down the ads display random positions. What should I change to display ads after every 5 items?
AdapterFile:
public class TQuoteAdapter extends RecyclerView.Adapter<TQuoteAdapter.ImageHolder> {
private int ad_count = 0;
List<QuotesModel> quotesList;
Context context;
int width;
DBHelper_dbfile dbHelper;
int[] grid_colors;
int c = 0;
public TQuoteAdapter(List<QuotesModel> quotesList, Context context) {
this.quotesList = quotesList;
this.context = context;
dbHelper = new DBHelper_dbfile(context);
try {
dbHelper.openDatabase();
} catch (SQLException sqle) {
throw sqle;
}
DisplayMetrics displayMetrics = context.getResources()
.getDisplayMetrics();
width = displayMetrics.widthPixels;
grid_colors = context.getResources().getIntArray(R.array.grid_colors);
}
public static class ImageHolder extends RecyclerView.ViewHolder {
private NativeAdView nativeAdView;
ImageView favIV;
TextView quoteTV;
LinearLayout share, copy, wapp,fbapp,instaapp;
CardView cardView;
public ImageHolder(#NonNull View itemView) {
super(itemView);
nativeAdView = itemView.findViewById(R.id.native_ad_view);
quoteTV = itemView.findViewById(R.id.quoteTV);
favIV = itemView.findViewById(R.id.favIV);
share = itemView.findViewById(R.id.share);
copy = itemView.findViewById(R.id.copy);
wapp = itemView.findViewById(R.id.wapp);
fbapp = itemView.findViewById(R.id.fbapp);
instaapp = itemView.findViewById(R.id.instaapp);
cardView = itemView.findViewById(R.id.cardView);
}
}
#NonNull
#Override
public ImageHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_tquote, parent, false);
return new ImageHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ImageHolder holder, int position) {
if(ad_count == 5){
AdLoader adLoader = new AdLoader.Builder(context,context.getString(R.string.native_unit_id))
.forNativeAd(new NativeAd.OnNativeAdLoadedListener() {
#Override
public void onNativeAdLoaded(#NonNull NativeAd nativeAd) {
populateNativeAdView(nativeAd,holder.nativeAdView);
if (onDestroy()) {
nativeAd.destroy();
}
}
})
.withAdListener(new AdListener() {
#Override
public void onAdFailedToLoad(LoadAdError adError) {
// Handle the failure by logging, altering the UI, and so on.
}
})
.withNativeAdOptions(new NativeAdOptions.Builder()
// Methods in the NativeAdOptions.Builder class can be
// used here to specify individual options settings.
.build())
.build();
adLoader.loadAd(new AdRequest.Builder().build());
ad_count = 0;
}else {
holder.quoteTV.setText(quotesList.get(position).getQuotes());
ad_count ++;
}
setAnimation(holder.itemView);
if (quotesList.get(position).getFavourite().equals("no")) {
holder.favIV.setImageResource(R.drawable.unpress_download);
} else {
holder.favIV.setImageResource(R.drawable.press_download);
}
holder.favIV.setOnClickListener(v -> {
if (Utills.hasPermissions(context, Utills.permissions)) {
ActivityCompat.requestPermissions((Activity) context, Utills.permissions, Utills.perRequest);
} else {
if (quotesList.get(position).getFavourite().equals("no")) {
dbHelper.addToFavourite("yes", quotesList.get(position).getId());
quotesList.get(position).setFavourite("yes");
} else {
dbHelper.addToFavourite("no", quotesList.get(position).getId());
quotesList.get(position).setFavourite("no");
}
notifyDataSetChanged();
}
});
int color = grid_colors[c];
c++;
if (c == grid_colors.length) {
c = 0;
}
holder.cardView.setCardBackgroundColor(color);
}
private void setAnimation(View view){
Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
view.setAnimation(animation);
}
protected boolean onDestroy() {
AdManager.destroyFbAd();
return false;
}
#Override
public int getItemCount() {
return quotesList.size();
}
private void populateNativeAdView(NativeAd nativeAd, NativeAdView nativeAdView) {
nativeAdView.setMediaView((MediaView) nativeAdView.findViewById(R.id.media_view));
nativeAdView.setCallToActionView(nativeAdView.findViewById(R.id.cta));
nativeAdView.setHeadlineView(nativeAdView.findViewById(R.id.primary));
nativeAdView.setAdvertiserView(nativeAdView.findViewById(R.id.secondary));
nativeAdView.setStarRatingView(nativeAdView.findViewById(R.id.rating_bar));
nativeAdView.setBodyView(nativeAdView.findViewById(R.id.body));
nativeAdView.setIconView(nativeAdView.findViewById(R.id.icon));
View headlineView = nativeAdView.getHeadlineView();
Objects.requireNonNull(headlineView);
((AppCompatTextView) headlineView).setText(nativeAd.getHeadline());
View bodyView = nativeAdView.getBodyView();
Objects.requireNonNull(bodyView);
((AppCompatTextView) bodyView).setText(nativeAd.getBody());
View callToActionView = nativeAdView.getCallToActionView();
Objects.requireNonNull(callToActionView);
((AppCompatButton) callToActionView).setText(nativeAd.getCallToAction());
MediaView mediaView = nativeAdView.getMediaView();
Objects.requireNonNull(mediaView);
MediaContent mediaContent = nativeAd.getMediaContent();
Objects.requireNonNull(mediaContent);
mediaView.setMediaContent(mediaContent);
if (nativeAd.getIcon() == null) {
View iconView = nativeAdView.getIconView();
Objects.requireNonNull(iconView);
iconView.setVisibility(View.INVISIBLE);
} else {
View iconView2 = nativeAdView.getIconView();
Objects.requireNonNull(iconView2);
((AppCompatImageView) iconView2).setImageDrawable(nativeAd.getIcon().getDrawable());
nativeAdView.getIconView().setVisibility(View.VISIBLE);
}
if (nativeAd.getStarRating() == null) {
View starRatingView = nativeAdView.getStarRatingView();
Objects.requireNonNull(starRatingView);
starRatingView.setVisibility(View.INVISIBLE);
} else {
View starRatingView2 = nativeAdView.getStarRatingView();
Objects.requireNonNull(starRatingView2);
((RatingBar) starRatingView2).setRating(nativeAd.getStarRating().floatValue());
nativeAdView.getStarRatingView().setVisibility(View.VISIBLE);
}
if (nativeAd.getAdvertiser() == null) {
View advertiserView = nativeAdView.getAdvertiserView();
Objects.requireNonNull(advertiserView);
advertiserView.setVisibility(View.INVISIBLE);
} else {
View advertiserView2 = nativeAdView.getAdvertiserView();
Objects.requireNonNull(advertiserView2);
((AppCompatTextView) advertiserView2).setText(nativeAd.getAdvertiser());
nativeAdView.getAdvertiserView().setVisibility(View.VISIBLE);
}
nativeAdView.setNativeAd(nativeAd);
nativeAdView.setVisibility(View.VISIBLE);
}
i am tried to stream video from uvc camera with agora video call api. but it doesn't work . but the uvc camera preview show proferly on '''''' .
public class VideoChatViewActivity extends AppCompatActivity implements CameraDialog.CameraDialogParent, CameraViewInterface.Callback{
private static final String TAG = VideoChatViewActivity.class.getSimpleName();
private static final int PERMISSION_REQ_ID = 22;
// Permission WRITE_EXTERNAL_STORAGE is not mandatory
// for Agora RTC SDK, just in case if you wanna save
// logs to external sdcard.
private static final String[] REQUESTED_PERMISSIONS = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA
};
private RtcEngine mRtcEngine;
private boolean mCallEnd;
private boolean mMuted;
private FrameLayout mLocalContainer;
private RelativeLayout mRemoteContainer;
private VideoCanvas mLocalVideo;
private VideoCanvas mRemoteVideo;
private ImageView mCallBtn;
private ImageView mMuteBtn;
private ImageView mSwitchCameraBtn;
// Customized logger view
private LoggerRecyclerView mLogView;
private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
#Override
public void onJoinChannelSuccess(String channel, final int uid, int elapsed) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLogView.logI("Join channel success, uid: " + (uid & 0xFFFFFFFFL));
}
});
}
#Override
public void onUserJoined(final int uid, int elapsed) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLogView.logI("First remote video decoded, uid: " + (uid & 0xFFFFFFFFL));
setupRemoteVideo(uid);
}
});
}
#Override
public void onUserOffline(final int uid, int reason) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLogView.logI("User offline, uid: " + (uid & 0xFFFFFFFFL));
onRemoteUserLeft(uid);
}
});
}
};
private void setupRemoteVideo(int uid) {
ViewGroup parent = mRemoteContainer;
if (parent.indexOfChild(mLocalVideo.view) > -1) {
parent = mLocalContainer;
}
if (mRemoteVideo != null) {
return;
}
SurfaceView view = RtcEngine.CreateRendererView(getBaseContext());
view.setZOrderMediaOverlay(parent == mLocalContainer);
parent.addView(view);
mRemoteVideo = new VideoCanvas(view, VideoCanvas.RENDER_MODE_HIDDEN, uid);
// Initializes the video view of a remote user.
mRtcEngine.setupRemoteVideo(mRemoteVideo);
}
private void onRemoteUserLeft(int uid) {
if (mRemoteVideo != null && mRemoteVideo.uid == uid) {
removeFromParent(mRemoteVideo);
// Destroys remote view
mRemoteVideo = null;
}
}
//usb
private static final int DEFAULT_CAPTURE_WIDTH = 1280;
private static final int DEFAULT_CAPTURE_HEIGHT = 720;
#BindView(R.id.camer_view)
public View mTextureView;
private static final String TAG1 = "Debug";
private UVCCameraHelper mCameraHelper;
private CameraViewInterface mUVCCameraView;
private AlertDialog mDialog;
private boolean isRequest;
private boolean isPreview;
private UVCCameraHelper.OnMyDevConnectListener listener = new UVCCameraHelper.OnMyDevConnectListener() {
#Override
public void onAttachDev(UsbDevice device) {
// request open permission
if (!isRequest) {
isRequest = true;
if (mCameraHelper != null) {
mCameraHelper.requestPermission(0);
}
}
}
#Override
public void onDettachDev(UsbDevice device) {
// close camera
if (isRequest) {
isRequest = false;
mCameraHelper.closeCamera();
showShortMsg(device.getDeviceName() + " is out");
}
}
#Override
public void onConnectDev(UsbDevice device, boolean isConnected) {
if (!isConnected) {
showShortMsg("fail to connect,please check resolution params");
isPreview = false;
} else {
isPreview = true;
showShortMsg("connecting");
// initialize seekbar
// need to wait UVCCamera initialize over
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Looper.prepare();
if(mCameraHelper != null && mCameraHelper.isCameraOpened()) {
}
Looper.loop();
}
}).start();
}
}
#Override
public void onDisConnectDev(UsbDevice device) {
showShortMsg("disconnecting");
}
};
//usb
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_chat_view);
ButterKnife.bind(this);//uvc
initUI();
mUVCCameraView = (CameraViewInterface) mTextureView;
mUVCCameraView.setCallback(this);
//mLocalContainer.setCallback(this);
mCameraHelper = UVCCameraHelper.getInstance();
mCameraHelper.setDefaultPreviewSize(1280,720);
mCameraHelper.initUSBMonitor(this, mUVCCameraView, listener);
mCameraHelper.setOnPreviewFrameListener(new AbstractUVCCameraHandler.OnPreViewResultListener() {
#Override
public void onPreviewResult(byte[] bytes) {
try {
AgoraVideoFrame frame = new AgoraVideoFrame();
frame.buf = bytes;
frame.format = AgoraVideoFrame.FORMAT_NV21;
frame.stride = DEFAULT_CAPTURE_WIDTH;
frame.height = DEFAULT_CAPTURE_HEIGHT;
frame.timeStamp = System.currentTimeMillis();
mRtcEngine.pushExternalVideoFrame(frame);
}catch (Exception e){
e.printStackTrace();
}
}
});
// Ask for permissions at runtime.
// This is just an example set of permissions. Other permissions
// may be needed, and please refer to our online documents.
if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID)) {
initEngineAndJoinChannel();
}
}
private void initUI() {
mLocalContainer = findViewById(R.id.local_video_view_container);
mRemoteContainer = findViewById(R.id.remote_video_view_container);
mCallBtn = findViewById(R.id.btn_call);
mMuteBtn = findViewById(R.id.btn_mute);
mSwitchCameraBtn = findViewById(R.id.btn_switch_camera);
mLogView = findViewById(R.id.log_recycler_view);
// Sample logs are optional.
showSampleLogs();
}
private void showSampleLogs() {
mLogView.logI("Welcome to Agora 1v1 video call");
mLogView.logW("You will see custom logs here");
mLogView.logE("You can also use this to show errors");
}
private boolean checkSelfPermission(String permission, int requestCode) {
if (ContextCompat.checkSelfPermission(this, permission) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode);
return false;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQ_ID) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED ||
grantResults[1] != PackageManager.PERMISSION_GRANTED ||
grantResults[2] != PackageManager.PERMISSION_GRANTED) {
showLongToast("Need permissions " + Manifest.permission.RECORD_AUDIO +
"/" + Manifest.permission.CAMERA);
finish();
return;
}
// Here we continue only if all permissions are granted.
// The permissions can also be granted in the system settings manually.
initEngineAndJoinChannel();
}
}
private void showLongToast(final String msg) {
this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
});
}
private void initEngineAndJoinChannel() {
initializeEngine();
setupVideoConfig();
setupLocalVideo();
joinChannel();
}
private void initializeEngine() {
try {
mRtcEngine = RtcEngine.create(getBaseContext(), getString(R.string.agora_app_id), mRtcEventHandler);
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
throw new RuntimeException("NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
}
}
private void setupVideoConfig() {
mRtcEngine.enableVideo();
mRtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
VideoEncoderConfiguration.VD_640x360,
VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15,
VideoEncoderConfiguration.STANDARD_BITRATE,
VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT));
}
private void setupLocalVideo() {
.
SurfaceView view = RtcEngine.CreateRendererView(getBaseContext());
view.setZOrderMediaOverlay(true);
mLocalContainer.addView(view);
mLocalVideo = new VideoCanvas(view, VideoCanvas.RENDER_MODE_HIDDEN, 0);
mRtcEngine.setupLocalVideo(mLocalVideo);
}
private void joinChannel() {
String token = getString(R.string.agora_access_token);
if (TextUtils.isEmpty(token) || TextUtils.equals(token, "#YOUR ACCESS TOKEN#")) {
token = null; // default, no token
}
mRtcEngine.joinChannel(token, "streaming", "Extra Optional Data", 0);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (!mCallEnd) {
leaveChannel();
}
RtcEngine.destroy();
}
private void leaveChannel() {
mRtcEngine.leaveChannel();
}
public void onLocalAudioMuteClicked(View view) {
mMuted = !mMuted;
mRtcEngine.muteLocalAudioStream(mMuted);
int res = mMuted ? R.drawable.btn_mute : R.drawable.btn_unmute;
mMuteBtn.setImageResource(res);
}
public void onSwitchCameraClicked(View view) {
mRtcEngine.switchCamera();
}
public void onCallClicked(View view) {
if (mCallEnd) {
startCall();
mCallEnd = false;
mCallBtn.setImageResource(R.drawable.btn_endcall);
} else {
endCall();
mCallEnd = true;
mCallBtn.setImageResource(R.drawable.btn_startcall);
}
showButtons(!mCallEnd);
}
private void startCall() {
setupLocalVideo();
joinChannel();
}
private void endCall() {
removeFromParent(mLocalVideo);
mLocalVideo = null;
removeFromParent(mRemoteVideo);
mRemoteVideo = null;
leaveChannel();
}
private void showButtons(boolean show) {
int visibility = show ? View.VISIBLE : View. SurfaceView view .GONE;
mMuteBtn.setVisibility(visibility);
mSwitchCameraBtn.setVisibility(visibility);
}
private ViewGroup removeFromParent(VideoCanvas canvas) {
if (canvas != null) {
ViewParent parent = canvas.view.getParent();
if (parent != null) {
ViewGroup group = (ViewGroup) parent;
group.removeView(canvas.view);
return group;
}
}
return null;
}
private void switchView(VideoCanvas canvas) {
ViewGroup parent = removeFromParent(canvas);
if (parent == mLocalContainer) {
if (canvas.view instanceof SurfaceView) {
((SurfaceView) canvas.view).setZOrderMediaOverlay(false);
}
mRemoteContainer.addView(canvas.view);
} else if (parent == mRemoteContainer) {
if (canvas.view instanceof SurfaceView) {
((SurfaceView) canvas.view).setZOrderMediaOverlay(true);
}
mLocalContainer.addView(canvas.view);
}
}
public void onLocalContainerClick(View view) {
switchView(mLocalVideo);
switchView(mRemoteVideo);
}
///uvc
#Override
protected void onStart() {
super.onStart();
// step.2 register USB event broadcast
if (mCameraHelper != null) {
mCameraHelper.registerUSB();
}
}
#Override
protected void onStop() {
super.onStop();
// step.3 unregister USB event broadcast
if (mCameraHelper != null) {
mCameraHelper.unregisterUSB();
}
}
private void showShortMsg(String msg) {
//
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
#Override
public USBMonitor getUSBMonitor(){ return mCameraHelper.getUSBMonitor();
}
#Override
public void onDialogResult(boolean canceled) {
if (canceled) {
showShortMsg("cancel");
}
}
#Override
public void onSurfaceCreated(CameraViewInterface cameraViewInterface, Surface surface) {
if (!isPreview && mCameraHelper.isCameraOpened()) {
mCameraHelper.startPreview(mUVCCameraView);
isPreview = true;
}
}
#Override
public void onSurfaceChanged(CameraViewInterface cameraViewInterface, Surface surface, int i, int i1) {
}
#Override
public void onSurfaceDestroy(CameraViewInterface cameraViewInterface, Surface surface) {
if (isPreview && mCameraHelper.isCameraOpened()) {
mCameraHelper.stopPreview();
isPreview = false;
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_chat_view);
initUI();
// Ask for permissions at runtime.
// This is just an example set of permissions. Other permissions
// may be needed, and please refer to our online documents.
if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID)) {
initEngineAndJoinChannel();
}
//xiaobing add
final View view = findViewById(R.id.camera_view);
mUVCCameraView = (CameraViewInterface)view;
mUSBMonitor = new USBMonitor(this, mOnDeviceConnectListener);
mUVCCameraView.setAspectRatio(previewWidth / (float)previewHeight);
mCameraHandler = UVCCameraHandler.createHandler(this,
mUVCCameraView, previewWidth,
previewHeight, BANDWIDTH_FACTORS[0],
firstDataCallBack);
}
//xiaobing add
private void startPreview() {
final SurfaceTexture st = mUVCCameraView.getSurfaceTexture();
mCameraHandler.startPreview(new Surface(st));
}
//xiaobing add
UvcCameraDataCallBack firstDataCallBack = new UvcCameraDataCallBack() {
#Override
public void getData(byte[] data) {
if (DEBUG) {
Log.v(TAG, "data callback:" + data.length);
}
AgoraVideoFrame frame = new AgoraVideoFrame();
frame.buf = data;
frame.format = AgoraVideoFrame.FORMAT_NV12;
frame.stride = previewWidth;
frame.height = previewHeight;
frame.timeStamp = System.currentTimeMillis();
mRtcEngine.pushExternalVideoFrame(frame);
}
};
//xiaobing add
#Override
protected void onStart() {
super.onStart();
if (DEBUG) Log.v(TAG, "onStart:");
mUSBMonitor.register();
if (mUVCCameraView != null)
mUVCCameraView.onResume();
if (!mCameraHandler.isOpened()) {
UsbManager um = (UsbManager) (getSystemService(Context.USB_SERVICE));
HashMap<String, UsbDevice> map = um.getDeviceList();
ArrayList<String> names = new ArrayList<>();
final ArrayList<UsbDevice> devices = new ArrayList<>();
for(Map.Entry<String, UsbDevice> item : map.entrySet()) {
String name = item.getValue().getProductName();
String vid = Integer.toHexString(item.getValue().getVendorId());
String pid = Integer.toHexString(item.getValue().getProductId());
String all = "" + name + " VID:" + vid
+ " PID:" + pid;
Log.v("xiaobing", "all:" + all);
names.add(all);
devices.add(item.getValue());
if(item.getValue().getProductId()==1383 && (item.getValue().getVendorId() == 3034)){
mDev = item.getValue();
mUSBMonitor.requestPermission(mDev);
//为了同时支持手机和眼镜,只有获得了眼镜的设备才选择本地视频
mRtcEngine.setExternalVideoSource(true, true, true);
mLogView.logI("使用USB摄像头!");
break;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
This is the gps class for mainactivity to call track user location
public class TrackGPS extends Service implements LocationListener{
private final Context mContext;
boolean checkGPS = false;
boolean checkNetwork = false;
boolean canGetLocation = false;
Location loc;
public double latitude;
public double longitude;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1;
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1;
protected LocationManager locationManager;
public TrackGPS(Context mContext) {
this.mContext = mContext;
getLocation();
}
This is the get the location code for longitude and latitude
private Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
checkGPS = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
checkNetwork = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
This is to check whether network and gps is turn on ?
if (!checkGPS && !checkNetwork) {
Toast.makeText(mContext, "No Service Provider Available", Toast.LENGTH_SHORT).show();
} else {
this.canGetLocation = true;
// First get location from Network Provider
if (checkNetwork) {
Toast.makeText(mContext, "Network", Toast.LENGTH_SHORT).show();
try {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
loc = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
if (loc != null) {
latitude = loc.getLatitude();
longitude = loc.getLongitude();
}
}
catch(SecurityException e){
Toast.makeText(TrackGPS.this, "please turn on gps", Toast.LENGTH_SHORT).show();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (checkGPS) {
Toast.makeText(mContext,"GPS",Toast.LENGTH_SHORT).show();
if (loc == null) {
try {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
loc = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (loc != null) {
latitude = loc.getLatitude();
longitude = loc.getLongitude();
}
}
} catch (SecurityException e) {
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return loc;
}
public double getLongitude() {
if (loc != null) {
longitude = loc.getLongitude();
}
return longitude;
}
public double getLatitude() {
if (loc != null) {
latitude = loc.getLatitude();
}
return latitude;
}
public boolean canGetLocation() {
return this.canGetLocation;
}
public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
alertDialog.setTitle("GPS Not Enabled");
alertDialog.setMessage("Do you wants to turn On GPS");
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
public void stopUsingGPS() {
// if (locationManager != null) {
//
// locationManager.removeUpdates(TrackGPS.this);
// }
try {
locationManager.removeUpdates(TrackGPS.this);
} catch (SecurityException e) {
Log.e("PERMISSION_EXCEPTION","PERMISSION_NOT_GRANTED");
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
how to get the location updated longitude and latitude from mainactivity when every time is change ?
#Override
public void onLocationChanged(Location location) {
if (loc != null) {
latitude = loc.getLatitude();
longitude = loc.getLongitude();
}
}
}
this is call in main activity to get the location
public void getLocation() {
gps = new TrackGPS(econtacts.this);
if (gps.canGetLocation()) {
longitude = gps.getLongitude();
latitude = gps.getLatitude();
// Toast.makeText(getApplicationContext(), "Longitude:" + Double.toString(longitude) + "\nLatitude:" + Double.toString(latitude), Toast.LENGTH_SHORT).show();
} else {
gps.showSettingsAlert();
}
}
I want to refresh the getview() of baseadapter each time when user click on multispinner. Also wants to deselect all the selected checkbox.
Anybody please help.
Blockquote
Below is my multispinner java class
public class MultiSpinnerSearch extends Spinner implements OnCancelListener {
private static final String TAG = MultiSpinnerSearch.class.getSimpleName();
private List<KeyPairBoolData> items;
private String defaultText = "";
private String spinnerTitle = "";
private SpinnerListener listener;
private int limit = 0;
private int selected = 0;
private LimitExceedListener limitListener;
MyAdapter adapter;
public static AlertDialog.Builder builder;
public static AlertDialog ad;
public MultiSpinnerSearch(Context context) {
super(context);
}
public MultiSpinnerSearch(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
TypedArray a = arg0.obtainStyledAttributes(arg1, R.styleable.MultiSpinnerSearch);
limit = a.getIndexCount();
for (int i = 0; i < limit; ++i) {
int attr = a.getIndex(i);
if (attr == R.styleable.MultiSpinnerSearch_hintText) {
spinnerTitle = a.getString(attr);
defaultText = spinnerTitle;
break;
}
}
Log.i(TAG, "spinnerTitle: " + spinnerTitle);
a.recycle();
}
public MultiSpinnerSearch(Context arg0, AttributeSet arg1, int arg2) {
super(arg0, arg1, arg2);
}
public void setLimit(int limit, LimitExceedListener listener) {
this.limit = limit;
this.limitListener = listener;
}
public List<KeyPairBoolData> getSelectedItems() {
List<KeyPairBoolData> selectedItems = new ArrayList<>();
for (KeyPairBoolData item : items) {
if (item.isSelected()) {
selectedItems.add(item);
}
}
return selectedItems;
}
public List<Long> getSelectedIds() {
List<Long> selectedItemsIds = new ArrayList<>();
for (KeyPairBoolData item : items) {
if (item.isSelected()) {
selectedItemsIds.add(item.getId());
}
}
return selectedItemsIds;
}
#Override
public void onCancel(DialogInterface dialog) {
// refresh text on spinner
StringBuilder spinnerBuffer = new StringBuilder();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected()) {
spinnerBuffer.append(items.get(i).getName());
spinnerBuffer.append(", ");
}
}
String spinnerText = spinnerBuffer.toString();
if (spinnerText.length() > 2)
spinnerText = defaultText;
else
spinnerText = defaultText;
ArrayAdapter<String> adapterSpinner = new ArrayAdapter<>(getContext(), R.layout.textview_for_spinner, new String[]{spinnerText});
setAdapter(adapterSpinner);
if (adapter != null)
adapter.notifyDataSetChanged();
listener.onItemsSelected(items);
}
#Override
public boolean performClick() {
builder = new AlertDialog.Builder(new ContextThemeWrapper(getContext(), R.style.Material_App_Dialog));
builder.setTitle(spinnerTitle);
final LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View view = inflater.inflate(R.layout.alert_dialog_listview_search, null);
builder.setView(view);
final ListView listView = (ListView) view.findViewById(R.id.alertSearchListView);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setFastScrollEnabled(false);
adapter = new MyAdapter(getContext(), items);
listView.setAdapter(adapter);
final TextView emptyText = (TextView) view.findViewById(R.id.empty);
listView.setEmptyView(emptyText);
final EditText editText = (EditText) view.findViewById(R.id.alertSearchEditText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
builder.setPositiveButton("Done", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.i(TAG, " ITEMS : " + items.size());
dialog.cancel();
}
});
builder.setOnCancelListener(this);
ad = builder.show();
return true;
}
public void setItems(List<KeyPairBoolData> items, int position, SpinnerListener listener) {
this.items = items;
this.listener = listener;
StringBuilder spinnerBuffer = new StringBuilder();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected()) {
spinnerBuffer.append(items.get(i).getName());
spinnerBuffer.append(", ");
}
}
if (spinnerBuffer.length() > 2)
defaultText = spinnerBuffer.toString().substring(0, spinnerBuffer.toString().length() - 2);
ArrayAdapter<String> adapterSpinner = new ArrayAdapter<>(getContext(), R.layout.textview_for_spinner, new String[]{defaultText});
setAdapter(adapterSpinner);
if (position != -1) {
items.get(position).setSelected(true);
//listener.onItemsSelected(items);
onCancel(null);
}
}
public interface LimitExceedListener {
void onLimitListener(KeyPairBoolData data);
}
//Adapter Class
public class MyAdapter extends BaseAdapter implements Filterable {
List<KeyPairBoolData> arrayList;
List<KeyPairBoolData> mOriginalValues; // Original Values
LayoutInflater inflater;
public MyAdapter(Context context, List<KeyPairBoolData> arrayList) {
this.arrayList = arrayList;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView textView;
CheckBox checkBox;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
Log.i(TAG, "getView() enter");
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.item_listview_multiple, parent, false);
holder.textView = (TextView) convertView.findViewById(R.id.alertTextView);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.alertCheckbox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final int backgroundColor = (position % 2 == 0) ? R.color.list_background : R.color.list_background;
convertView.setBackgroundColor(ContextCompat.getColor(getContext(), backgroundColor));
if (position==0)
{
holder.textView.setTextColor(Color.BLACK);
}
if (position==3)
{
holder.textView.setTextColor(Color.GREEN);
convertView.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.list_selected));
}
final KeyPairBoolData data = arrayList.get(position);
holder.textView.setText(data.getName());
holder.textView.setTypeface(null, Typeface.NORMAL);
holder.checkBox.setChecked(data.isSelected());
convertView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (data.isSelected()) { // unselect
selected--;
} else if (selected == limit) { // select with limit
if (limitListener != null)
limitListener.onLimitListener(data);
return;
} else { // selected
selected++;
}
final ViewHolder temp = (ViewHolder) v.getTag();
temp.checkBox.setChecked(!temp.checkBox.isChecked());
data.setSelected(!data.isSelected());
Log.i(TAG, "On Click Selected Item : " + data.getName() + " : " + data.isSelected());
}
});
holder.checkBox.setTag(holder);
return convertView;
}
#SuppressLint("DefaultLocale")
#Override
public Filter getFilter() {
return new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
arrayList = (List<KeyPairBoolData>) results.values; // has the filtered values
notifyDataSetChanged(); // notifies the data with new filtered values
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults(); // Holds the results of a filtering operation in values
List<KeyPairBoolData> FilteredArrList = new ArrayList<>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<>(arrayList); // saves the original data in mOriginalValues
}
/********
*
* If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values
* else does the Filtering and returns FilteredArrList(Filtered)
*
********/
if (constraint == null || constraint.length() == 0) {
// set the Original result to return
results.count = mOriginalValues.size();
results.values = mOriginalValues;
} else {
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < mOriginalValues.size(); i++) {
Log.i(TAG, "Filter : " + mOriginalValues.get(i).getName() + " -> " + mOriginalValues.get(i).isSelected());
String data = mOriginalValues.get(i).getName();
if (data.toLowerCase().contains(constraint.toString())) {
FilteredArrList.add(mOriginalValues.get(i));
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
}
}
}
And from my main activity
MultiSpinnerSearch searchSpinner = (MultiSpinnerSearch) findViewById(R.id.searchMultiSpinner);
searchSpinner.setItems(listArray, -1, new SpinnerListener() {
#Override
public void onItemsSelected(List<KeyPairBoolData> items) {
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected()) {
Log.i("TAG", i + " : " + items.get(i).getName() + " : " + items.get(i).isSelected());
FlashMessage(i + " : " + items.get(i).getName() + " : " + items.get(i).isSelected());
if (GroupName.equals(""))
{
GroupName=GroupName+items.get(i).getName();
Group_stuid=Group_stuid+student_idlist[i+1];
}
else
{
GroupName=GroupName+","+items.get(i).getName();
Group_stuid=Group_stuid+"#"+student_idlist[i+1];
}
}
}
FlashMessage("grp name : "+GroupName);
FlashMessage("grp id : "+Group_stuid);
Audiofilename=appfunct.checkfile(eventType,acdses_sct,class_sct,category_sct,subject_sct,test_sct,Group_stuid,GroupName);
outfolder=appfunct.outfldr();
Group_stuid=Group_stuid.replaceAll("/","-");
File create_stuid=new File(outfolder.toString()+"/"+Group_stuid);
if(!create_stuid.exists()) {
create_stuid.mkdirs();
}
FlashMessage(""+GroupFoldername);
Group_listFiles=appfunct.showlistfiles(GroupFoldername);
if (Group_listFiles != null)
{
final CustomGroupFolder_ListDispaly adapter1 = new CustomGroupFolder_ListDispaly(Group_recording.this,R.layout.group_item_listview,Group_listFiles);
group_listview.setAdapter(adapter1);
}
GroupName="";
Group_stuid="";
selected_students=appfunct.getSelectedNamesGroup(GroupFoldername);
}
});
FlashMessage("out : grp id "+Group_stuid);
searchSpinner.setLimit(2, new MultiSpinnerSearch.LimitExceedListener() {
#Override
public void onLimitListener(KeyPairBoolData data) {
Toast.makeText(getApplicationContext(),
"Limit exceed ", Toast.LENGTH_LONG).show();
}
});
apply this to your adapter adapter.notifyDataSetChanged();
How to Create Geo fence(Creating and Monitoring Geo fences) on current latitude,longitude.
I am trying multiple example but not create.
Using this code:
public Geofence geofence(float radius, double latitude, double longitude) {
String id = UUID.randomUUID().toString();
return new Geofence.Builder()
.setRequestId(id)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.setCircularRegion(latitude, longitude, radius)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build();
}
There's this tutorial from Google, that's very easy to follow:
http://io2015codelabs.appspot.com/codelabs/geofences
There's also a course at Udacity that teaches location services, including geofences:
https://www.udacity.com/course/google-location-services-on-android--ud876-1
Add Google Play Services to Gradle File:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
compile 'com.google.android.gms:play-services:7.3.0'
}
Add to Manifest File:
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Add to Activity's XML Layout file:
<Button
android:id="#+id/add_geofences_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:onClick="addGeofencesButtonHandler"
android:text="Add GeoFences" />
Add to Activity's Java File:
public class MainActivity extends Activity
implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
ResultCallback<Status>{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAddGeofencesButton = (Button) findViewById(R.id.add_geofences_button);
// Empty list for storing geofences.
mGeofenceList = new ArrayList<Geofence>();
// Get the geofences used. Geofence data is hard coded in this sample.
populateGeofenceList();
// Kick off the request to build GoogleApiClient.
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
public void populateGeofenceList() {
for (Map.Entry<String, LatLng> entry : Constants.LANDMARKS.entrySet()) {
mGeofenceList.add(new Geofence.Builder()
.setRequestId(entry.getKey())
.setCircularRegion(
entry.getValue().latitude,
entry.getValue().longitude,
Constants.GEOFENCE_RADIUS_IN_METERS
)
.setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
}
}
#Override
protected void onStart() {
super.onStart();
if (!mGoogleApiClient.isConnecting() || !mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnecting() || mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public void onConnected(Bundle connectionHint) {
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Do something with result.getErrorCode());
}
#Override
public void onConnectionSuspended(int cause) {
mGoogleApiClient.connect();
}
public void addGeofencesButtonHandler(View view) {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(this, "Google API Client not connected!", Toast.LENGTH_SHORT).show();
return;
}
try {
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
getGeofencingRequest(),
getGeofencePendingIntent()
).setResultCallback(this); // Result processed in onResult().
} catch (SecurityException securityException) {
// Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission.
}
}
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private PendingIntent getGeofencePendingIntent() {
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling addgeoFences()
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public void onResult(Status status) {
if (status.isSuccess()) {
Toast.makeText(
this,
"Geofences Added",
Toast.LENGTH_SHORT
).show();
} else {
// Get the status code for the error and log it using a user-friendly message.
String errorMessage = GeofenceErrorMessages.getErrorString(this,
status.getStatusCode());
}
}
Create a java file called Constans:
public class Constants {
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = 12 * 60 * 60 * 1000;
public static final float GEOFENCE_RADIUS_IN_METERS = 20;
public static final HashMap<String, LatLng> LANDMARKS = new HashMap<String, LatLng>();
static {
// San Francisco International Airport.
LANDMARKS.put("Moscone South", new LatLng(37.783888,-122.4009012));
// Googleplex.
LANDMARKS.put("Japantown", new LatLng(37.785281,-122.4296384));
// Test
LANDMARKS.put("SFO", new LatLng(37.621313,-122.378955));
}
}
Create a java file called GeofenceTransitionsIntentService:
public class GeofenceTransitionsIntentService extends IntentService {
protected static final String TAG = "GeofenceTransitionsIS";
public GeofenceTransitionsIntentService() {
super(TAG); // use TAG to name the IntentService worker thread
}
#Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
if (event.hasError()) {
Log.e(TAG, "GeofencingEvent Error: " + event.getErrorCode());
return;
}
}
String description = getGeofenceTransitionDetails(event);
sendNotification(description);
}
private static String getGeofenceTransitionDetails(GeofencingEvent event) {
String transitionString =
GeofenceStatusCodes.getStatusCodeString(event.getGeofenceTransition());
List triggeringIDs = new ArrayList();
for (Geofence geofence : event.getTriggeringGeofences()) {
triggeringIDs.add(geofence.getRequestId());
}
return String.format("%s: %s", transitionString, TextUtils.join(", ", triggeringIDs));
}
private void sendNotification(String notificationDetails) {
// Create an explicit content Intent that starts MainActivity.
Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
// Get a PendingIntent containing the entire back stack.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class).addNextIntent(notificationIntent);
PendingIntent notificationPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// Get a notification builder that's compatible with platform versions >= 4
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// Define the notification settings.
builder.setColor(Color.RED)
.setContentTitle(notificationDetails)
.setContentText("Click notification to return to App")
.setContentIntent(notificationPendingIntent)
.setAutoCancel(true);
// Fire and notify the built Notification.
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, builder.build());
}
You should probably stick to their tutorial instead of copying and pasting the code to your project :D
Source
I am doing it in a Service
GeolocationService
public class GeolocationService extends Service implements LocationListener,
GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {
private Context mContext;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
// private Location mLastLocation;
private PendingIntent mGeofencePendingIntent;
private String mLastUpdateTime;
public static boolean isGeoFenceAdded = false;
private boolean mUpdateGeoFence = false;
private boolean mRemoveAllGeoFence = false;
private static final long TIME_OUT = 100;
#Override
public void onCreate() {
super.onCreate();
mContext = GeolocationService.this;
buildGoogleApiClient();
createLocationRequest();
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
/// FIXME: 2/15/2017 connect should be handled through onStart and onStop of Activity
mGoogleApiClient.connect();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);//set the interval in which you want to get locations
mLocationRequest.setFastestInterval(2500);//if a location is available sooner you can get it (i.e. another app is using the location services)
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
if (intent.getAction() != null) {
if (intent.getAction().equals(Constants.ACTION_UPDATE_GEOFENCE)) {
//// FIXME: 3/21/2017 you can also receive triggered location here..
mUpdateGeoFence = true;
isGeoFenceAdded = false;
mRemoveAllGeoFence = false;
} else if (intent.getAction().equals(Constants.ACTION_ADD_GEOFENCE)) {
mUpdateGeoFence = false;
isGeoFenceAdded = false;
mRemoveAllGeoFence = false;
} else if (intent.getAction().equals(Constants.ACTION_REMOVE_ALL_GEOFENCE)) {
mRemoveAllGeoFence = true;
isGeoFenceAdded = true;
mUpdateGeoFence = false;
}
}
}
//try this for null as http://stackoverflow.com/a/25096022/3496570
///return START_REDELIVER_INTENT;
return super.onStartCommand(intent, flags, startId);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onConnected(#Nullable Bundle bundle) {
startLocationUpdates(mContext);
}
#Override
public void onConnectionSuspended(int i) {
switch (i) {
case CAUSE_SERVICE_DISCONNECTED:
/*if (onLocationUpdateListener != null)
onLocationUpdateListener.onError(
Constants.ErrorType.SERVICE_DISCONNECTED);*/
break;
case CAUSE_NETWORK_LOST:
/*if (onLocationUpdateListener != null)
onLocationUpdateListener.onError(
Constants.ErrorType.NETWORK_LOST);*/
break;
}
//// FIXME: 3/2/2017 check is it right to check for re Connecting..
//--- http://stackoverflow.com/a/27350444/3496570
///mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
/*if (onLocationUpdateListener != null)
onLocationUpdateListener.onError(
Constants.ErrorType.CONNECTION_FAIL);*/
//// FIXME: 3/3/2017 call a transparent activity and call startResolutionForresult from their and return result to service using action
if (connectionResult.hasResolution()) {
/*try {
// !!!
connectionResult.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}*/
} else {
/*GoogleApiAvailability.getInstance().getErrorDialog(mContext, connectionResult.getErrorCode(), 0).show();
return;*/
}
}
#Override
public void onLocationChanged(final Location currentLocation) {
setupGeoFencePoints(currentLocation);
/*if (onLocationUpdateListener != null && mLocation != null) {
onLocationUpdateListener.onLocationChange(mLocation);
}*/
}
private void setupGeoFencePoints(final Location currentLocation) {
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
// mLastLocation = currentLocation;
if (currentLocation != null && isGeoFenceAdded == false)
{
if (mUpdateGeoFence) {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient
, getGeofencePendingIntent()).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
//if old geoFence's remove successfully then add new ones.
addGeoFences(currentLocation);
}
}
});
}
} else {
addGeoFences(currentLocation);
}
}
else if(isGeoFenceAdded && mRemoveAllGeoFence ){
if (mGoogleApiClient != null && mGoogleApiClient.isConnected())
{
LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient
, mGeofencePendingIntent).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
mRemoveAllGeoFence = false;
isGeoFenceAdded = false;
//if old geoFence's remove successfully then do nothing.
stopLocationUpdate();
if (mGoogleApiClient != null && mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
}
}
});
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
stopLocationUpdate();
if (mGoogleApiClient != null && mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
}
private void startLocationUpdates(final Context mContext) {
if (ActivityCompat.checkSelfPermission(mContext,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(mContext,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
// mLastLocation = FusedLocationApi.getLastLocation(mGoogleApiClient);
PendingResult<Status> pendingResult = FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
pendingResult.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
//update it's code too.
if (status.isSuccess()) {
Toast.makeText(mContext, "location Update Started",
Toast.LENGTH_SHORT).show();
} else if (status.hasResolution()) {
Toast.makeText(mContext, "Open intent to resolve",
Toast.LENGTH_SHORT).show();
}
}
});
}
private void stopLocationUpdate() {
//three types of constructor ..
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
}
public void addGeoFences(Location currentLocation) {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
try {
if (getGeofencingRequest(currentLocation) != null) {
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
// The GeofenceRequest object.
getGeofencingRequest(currentLocation),
// A pending intent that that is reused when calling removeGeofences(). This
// pending intent is used to generate an intent when a matched geofence
// transition is observed.
getGeofencePendingIntent()
//).await(TimeOut,TimeUnit.Miilisecponds);
).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Toast.makeText(mContext, "Geo Fence Added", Toast.LENGTH_SHORT).show();
isGeoFenceAdded = true;
mRemoveAllGeoFence = false;
mUpdateGeoFence = false;
/// FIXME: 3/2/2017 I didn't have to draw it.
///broadcastDrawGeoFenceOnMap();
} else {
String errorMessage = getErrorString(mContext, status.getStatusCode());
Toast.makeText(mContext, "Status Failed", Toast.LENGTH_SHORT).show();
}
}
}); // Result processed in onResult().
}
} catch (SecurityException securityException) {
securityException.printStackTrace();
// Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission.
//logSecurityException(securityException);
}
}
}
private PendingIntent getGeofencePendingIntent() {
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
// Reuse the PendingIntent if we already have it.
/// FIXME: 2/9/2017 Update the below class with a receiever..
Intent intent = new Intent(mContext, GeofenceReceiver.class);///GeofenceTransitionsIntentService.class);
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling
// addGeofences() and removeGeofences().
/// FIXME: 3/1/2017 It must be reciever not IntentService
mGeofencePendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
private GeofencingRequest getGeofencingRequest(Location mCurrentLocation) {
/// FIXME: 2/13/2017 mLastLocation can be null because it will take time for the first time.
/// this request should be called after first mLastLocation has been fetched..
GeofencingRequest geofencingRequest = null;
if (mCurrentLocation != null) {
List<SimpleGeofence> simpleFenceList = SimpleGeofenceStore
.getInstance().getLatestGeoFences(mCurrentLocation);
simpleFenceList.add(new SimpleGeofence("currentLocation",
mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude(),
100f, GEOFENCE_EXPIRATION_IN_MILLISECONDS,
Geofence.GEOFENCE_TRANSITION_EXIT));
ListSharedPref.saveAnyTypeOfList(ListSharedPref.GEO_FENCE_LIST_KEY, simpleFenceList);
GeofencingRequest.Builder geofencingRequestBuilder = new GeofencingRequest.Builder();
geofencingRequestBuilder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
for (SimpleGeofence simpleGeofence : simpleFenceList)
geofencingRequestBuilder.addGeofence(simpleGeofence.toGeofence());
geofencingRequest = geofencingRequestBuilder.build();
}
// Return a GeofencingRequest.
return geofencingRequest;
}
}
GeofenceReceiver
public class GeofenceReceiver extends IntentService {
public static final int NOTIFICATION_ID = 1;
public GeofenceReceiver() {
super("GeofenceReceiver");
}
#Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent geoEvent = GeofencingEvent.fromIntent(intent);
Location triggredLocation = geoEvent.getTriggeringLocation();
if (geoEvent.hasError()) {
Log.d(HomeActivity.TAG, "Error GeofenceReceiver.onHandleIntent");
} else {
Log.d(HomeActivity.TAG, "GeofenceReceiver : Transition -> "
+ geoEvent.getGeofenceTransition());
int transitionType = geoEvent.getGeofenceTransition();
if (transitionType == Geofence.GEOFENCE_TRANSITION_ENTER
|| transitionType == Geofence.GEOFENCE_TRANSITION_DWELL
|| transitionType == Geofence.GEOFENCE_TRANSITION_EXIT) {
List<Geofence> triggerList = geoEvent.getTriggeringGeofences();
//if(triggerList.g)
Type listType = new TypeToken<ArrayList<SimpleGeofence>>(){}.getType();
List<SimpleGeofence> geoFenceList = GenericPref.readAnyTypeOfList(GenericPref.GEO_FENCE_LIST_KEY,listType);
for (Geofence geofence : triggerList)
{
/*SimpleGeofence sg = SimpleGeofenceStore.getInstance()
.getSimpleGeofences().get(geofence.getRequestId());*/
SimpleGeofence sg = null;
for(SimpleGeofence simpleGeofence : geoFenceList){
if(simpleGeofence.getId().equalsIgnoreCase(geofence.getRequestId())){
sg = simpleGeofence;
break;
}
}
String transitionName = "";
switch (transitionType) {
case Geofence.GEOFENCE_TRANSITION_DWELL:
transitionName = "dwell";
break;
case Geofence.GEOFENCE_TRANSITION_ENTER:
transitionName = "enter";
String date = DateFormat.format("yyyy-MM-dd hh:mm:ss",
new Date()).toString();
EventDataSource eds = new EventDataSource(
getApplicationContext());
eds.create(transitionName, date, geofence.getRequestId());
eds.close();
GeofenceNotification geofenceNotification = new GeofenceNotification(
this);
if(sg != null){
geofenceNotification
.displayNotification(sg, transitionType);
}
break;
case Geofence.GEOFENCE_TRANSITION_EXIT:
transitionName = "exit";
broadcastUpdateGeoFences();
//update your List
// Unregister all geoFences and reRegister it again
break;
}
}
}
}
}
public void broadcastUpdateGeoFences() {
//// FIXME: 3/2/2017 what if app is closed
HomeActivity.geofencesAlreadyRegistered = false;
MainActivity.isGeoFenceAdded = false;
Intent intent = new Intent(Constants.RECEIVER_GEOFENCE);
intent.putExtra("done", 1);
sendBroadcast(intent);
}
}