DocumentsContract.copyDocument - file

I have a problem with DocumentsContract.copyDocument
Each time my program crashes: "java.lang.UnsupportedOperationException: Copy not supported"
The curious thing is the below-listed actions are working fine!!
DocumentsContract.moveDocument
DocumentsContract.deleteDocument
DocumentsContract.renameDocument
DocumentsContract.createDocument
Permission to SD card access is apparently granted (above actions would fail without permission)
How come document moving, deleting and renaming is supported but not copying?
Can anyone help me with this issue?
Is there a great conceptual difference between copyDocument and moveDocument. Why move does work and copy does not?
Any hint will be highly appreciated
package com.example.forum14_11_2020;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.documentfile.provider.DocumentFile;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.UriPermission;
import android.net.Uri;
import android.os.Bundle;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.provider.DocumentsContract;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
public class MainActivity extends AppCompatActivity {
Uri uri;
DocumentFile pickedDir;
Button Button1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button1 = new Button(MainActivity.this);
Button1 = findViewById(R.id.button1);
Button1.setOnClickListener(onClickListener_Button1);
takeCardUriPermission("storage/1619-0D07");
}
View.OnClickListener onClickListener_Button1 = new View.OnClickListener() {
#Override
public void onClick(View v) {
uri = getUri();
pickedDir = DocumentFile.fromTreeUri(getBaseContext(), uri);
DocumentFile file = pickedDir.findFile("attempt.txt");
DocumentFile folder = pickedDir.findFile("folder");
try {
//DocumentsContract.moveDocument(getContentResolver(), file.getUri(), folder.getUri(), folder.getUri()); // does work!
//DocumentsContract.deleteDocument(getContentResolver(), file.getUri()); // does work!
//DocumentsContract.renameDocument(getContentResolver(), file.getUri(), file.getName() + "_rename"); // does work!
DocumentsContract.copyDocument(getContentResolver(), file.getUri(), folder.getUri()); // does not work
} catch (UnsupportedOperationException | FileNotFoundException e) {
e.printStackTrace();
e.getMessage();
}
}
};
public void takeCardUriPermission(String sdCardRootPath) {
int stop=1;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
File sdCard = new File(sdCardRootPath);
StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
StorageVolume storageVolume = storageManager.getStorageVolume(sdCard);
Intent intent = storageVolume.createAccessIntent(null);
try {
startActivityForResult(intent, 4010);
} catch (ActivityNotFoundException e) {
}
}
}
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 4010) {
Uri uri = data.getData();
grantUriPermission(getPackageName(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
Intent.FLAG_GRANT_READ_URI_PERMISSION);
final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
Intent.FLAG_GRANT_READ_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(uri, takeFlags);
}
}
public Uri getUri() {
List<UriPermission> persistedUriPermissions = getContentResolver().getPersistedUriPermissions();
if (persistedUriPermissions.size() > 0) {
UriPermission uriPermission = persistedUriPermissions.get(0);
return uriPermission.getUri();
}
return null;
}
}

Related

Remove item from a RecyclerView list based on status of a checkbox

I have a list application what is uses RecyclerView.
Each line has got a button, a checkbox and 2 textview.
All object is defined the RecyclerView clas, but I would like to check the checkbox status in the Main class and evaluate the status and remove the item from the list and from the SharedPreferences where the checkbox is checked
Main class is here:
package com.example.homehandling;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class ToDoList extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener, View.OnClickListener {
public MyRecyclerViewAdapter adapter;
public Button btn;
public SharedPreferences sharedPreferences;
public SharedPreferences.Editor myEdit;
public LinkedList<String> items, remain_days, prio;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shoppinglist);
sharedPreferences = getSharedPreferences("ToDoList", Context.MODE_PRIVATE);
myEdit = sharedPreferences.edit();
btn = findViewById(R.id.button);
items = new LinkedList<>();
remain_days = new LinkedList<>();
prio = new LinkedList<>();
RecyclerView recyclerView = findViewById(R.id.list);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyRecyclerViewAdapter(this,items,remain_days,prio);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
btn.setOnClickListener(this);
StartDisplay();
}
#Override
public void onItemClick(View view, int position) {
}
#Override
public void onClick(View v) {
Intent NewTLItem = new Intent(ToDoList.this, NewTLItem.class);
startActivity(NewTLItem);
}
#Override
public void onResume() {
super.onResume();
StartDisplay();
}
public void StartDisplay()
{
sharedPreferences = getSharedPreferences("ToDoList", Context.MODE_PRIVATE);
Map<String, ?> allEntries = sharedPreferences.getAll();
items.clear();
prio.clear();
remain_days.clear();
for (Map.Entry<String, ?> entry : allEntries.entrySet())
{
String key_word = entry.getKey();
String [] item_total = entry.getValue().toString().split(";");
if(key_word.contains("_")) key_word = key_word.replace("_"," ");
items.add(key_word);
remain_days.add(Long.toString(DateCalc(item_total[0])));
prio.add(item_total[1]);
}
adapter.notifyDataSetChanged();
}
public long DateCalc(String startdate)
{
Date system_date, due_date;
long diff_date = 0;
String currentDate = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(new Date());
SimpleDateFormat dates = new SimpleDateFormat("dd-MM-yyyy");
try {
system_date = dates.parse(currentDate);
due_date = dates.parse(startdate);
diff_date = (due_date.getTime()-system_date.getTime())/86400000;
} catch (ParseException e) {
e.printStackTrace();
}
return diff_date;
}
}
At now the item is removed when the whole line is touched. I would like to exchange to if only the Checkbox is "true".
At now the remove method is in the public void onItemClick(View view, int position) function.
I would like to put the content of the OnItemClick method to "if" part of CheckBox status.
Here is the RecyclerView class:
package com.example.homehandling;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder>
{
public List<String> mData, subdata, subdata2;
public LayoutInflater mInflater;
public ItemClickListener mClickListener;
public Context context;
public CheckBox done;
MyRecyclerViewAdapter(Context context, List<String> data, List<String> subdata, List<String> subdata2) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
this.subdata = subdata;
this.subdata2 = subdata2;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String meta_data = mData.get(position);
String meta_subdata = subdata.get(position);
String meta_subdata2 = subdata2.get(position);
holder.myTextView.setText(meta_data);
holder.subtext.setText(meta_subdata +" "+ meta_subdata2);
holder.add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String[] item_param = holder.myTextView.getText().toString().split(" ");
final Intent intent;
intent = new Intent(context, NewSLItem.class);
intent.putExtra("param",item_param[0]);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return mData.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
public TextView myTextView, subtext;
public Button add;
public ViewHolder(View itemView)
{
super(itemView);
context = itemView.getContext();
myTextView = itemView.findViewById(R.id.tvAnimalName);
subtext = itemView.findViewById(R.id.subtext);
add = itemView.findViewById(R.id.add);
done = itemView.findViewById(R.id.done);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view)
{
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
String getItem(int id) {return mData.get(id);
}
void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
public interface ItemClickListener
{
void onItemClick(View view, int position);
}
}
if(adapter.done.isChecked())should work I think, but I got null opbject reference exception.
Maybe the problem is that the checkbox is in the RecyclerView layout and not in Main class layout, but I am not sure.
Is it possible to handle the Checkbox methods from other class, and if yes, then where should I improve the code?

Incompatible types. Found: 'java.util.ArrayList<java.lang.Object>', required: 'java.util.ArrayList<UserLocation>'

So I am creating a route planner app in Android Studio and its giving me the error in the title of this question
Heres my code
import android.Manifest;
import android.app.Fragment;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.example.destinationrouteplanner.R;
import com.example.destinationrouteplanner.adapters.UserRecyclerAdapter;
import com.example.destinationrouteplanner.models.MarkerCluster;
import com.example.destinationrouteplanner.models.User;
import com.example.destinationrouteplanner.util.MyClusterManagerRenderer;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.maps.android.clustering.ClusterManager;
import java.util.ArrayList;
public class UserListFragment extends Fragment implements OnMapReadyCallback
{
private static final String TAG = "UserListFragment";
private RecyclerView mUserListRecyclerView;
private MapView mMapView;
private ArrayList<User> mUserList = new ArrayList<>();
//private UserRecyclerAdapter mUserRecyclerAdapter;
private ArrayList<UserLocation> mUserLocations = new ArrayList<>();
private UserRecyclerAdapter mUserRecyclerAdapter;
private GoogleMap mGoogleMap;
private LatLngBounds mMapBoundary;
private UserLocation mUserPosition;
private ClusterManager mClusterManager;
private MyClusterManagerRenderer mClusterManagerRenderer;
private ArrayList<MarkerCluster> mClusterMarkers = new ArrayList<>();
public static UserListFragment newInstance() {
return new UserListFragment();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mUserList = getArguments().getParcelableArrayList(getString(R.string.intent_user_list));
}
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_user_list, container, false);
mUserListRecyclerView = view.findViewById(R.id.user_list_recycler_view);
mMapView = view.findViewById(R.id.user_list_map);
initUserListRecyclerView();
initGoogleMap(savedInstanceState);
return view;
}
private void initGoogleMap(Bundle savedInstanceState){
// *** IMPORTANT ***
// MapView requires that the Bundle you pass contain _ONLY_ MapView SDK
// objects or sub-Bundles.
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY);
}
mMapView.onCreate(mapViewBundle);
mMapView.getMapAsync(this);
}
private void initUserListRecyclerView() {
mUserRecyclerAdapter = new UserRecyclerAdapter(mUserList);
mUserListRecyclerView.setAdapter(mUserRecyclerAdapter);
mUserListRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Bundle mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE_KEY);
if (mapViewBundle == null) {
mapViewBundle = new Bundle();
outState.putBundle(MAPVIEW_BUNDLE_KEY, mapViewBundle);
}
mMapView.onSaveInstanceState(mapViewBundle);
}
#Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
#Override
public void onStart() {
super.onStart();
mMapView.onStart();
}
#Override
public void onStop() {
super.onStop();
mMapView.onStop();
}
#Override
public void onMapReady(GoogleMap map) {
if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
map.setMyLocationEnabled(true);
mGoogleMap = map;
addMapMarkers();
}
#Override
public void onPause() {
mMapView.onPause();
super.onPause();
}
#Override
public void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
private void addMapMarkers()
{
if (mGoogleMap !=null)
{
if(mClusterManager == null)
{
mClusterManager = new ClusterManager<MarkerCluster>(getActivity().getApplicationContext(), mGoogleMap);
}
if (mClusterManagerRenderer == null)
{
mClusterManagerRenderer = new MyClusterManagerRenderer(getActivity(), mGoogleMap, mClusterManager);
mClusterManager.setRenderer(mClusterManagerRenderer);
}
for (UserLocation userLocation: mUserLocations)
{
Log.d(TAG, "AddMapMarkers: location: " + userLocation.getGeo_point().toString());
try {
String snippet = "";
if (userLocation.getUser().getUser_id().equals(FirebaseAuth.getInstance().getUid()))
{
snippet = "This is you";
}else {
snippet = "Determine route to " + userLocation.getUser().getUsername() + "?";
}
int avatar = R.drawable.cwm_logo; //Set the default avatar
try {
avatar = Integer.parseInt(userLocation.getUser().getAvatar());
}catch (NumberFormatException e)
{
Log.d(TAG, "addMapMarkers: no avatar for: " + userLocation.getUser().getUsername() + ", setting default");
}
MarkerCluster newMarkerCluster = new MarkerCluster(new LatLng(userLocation.getGeo_point().getLatitude(), userLocation.getGeo_point().getLongitude(), userLocation.getUser().getUsername(), snippet, avatar, userLocation.getUser()));
mClusterManager.addItem(newMarkerCluster);
mClusterMarkers.add(newMarkerCluster);
}catch (NullPointerException e)
{
Log.e(TAG "addMapMarkers: NullPointerException: " + e.getMessage());
}
}
mClusterManager.cluster();
setCameraView();
}
}
private void setCameraView()
{
double bottomBoundary = mUserPosition.getGeo_point().getLatitude() - .1;
double leftBoundary = mUserPosition.getGeo_point().getLongitude() - .1;
double topBoundary = mUserPosition.getGeo_point().getLatitude() - .1;
double rightBoundary = mUserPosition.getGeo_point().getLongitude() - .1;
}
#Override
public void onMapReady(#NonNull GoogleMap googleMap) {
}
}
I tired using the answer to this question but not working
Required type:
ArrayList
Provided:
ArrayList
no instance(s) of type variable(s) exist so that UserLocation conforms to Object

I am unable to get video to play reliably in codenameone

I am at the point of abandoning using codenameone to build an app that allows me to play video from storage or to capture and play. Its either it is playing but no video is showing (most common ) or it plays only once and thats it - the fast forward and rewind buttons not working. I don't know if this is a simulator problem/limitation or whether I just don't know what I am doing.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.ixzdore.ziem.renderer.widgets;
import com.codename1.capture.Capture;
import com.codename1.components.ImageViewer;
import com.codename1.components.MediaPlayer;
import com.codename1.io.FileSystemStorage;
import com.codename1.io.Log;
import static com.codename1.io.Log.e;
import com.codename1.media.Media;
import com.codename1.media.MediaManager;
import com.codename1.ui.Container;
import com.codename1.ui.Display;
import com.codename1.ui.Image;
import com.codename1.ui.Label;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.layouts.BorderLayout;
import com.ixzdore.ziem.models.DocumentElement;
import com.ixzdore.ziem.models.ReportDocument;
import java.io.IOException;
/**
*
* #author jamesagada
*/
public class NVideo extends Widget {
private final Label _imageLabel = new Label();
private MediaPlayer _mPlayer;
private Container imageVideoContainer;
public NVideo(DocumentElement element, ReportDocument doc, Boolean isEditing) {
super(element, doc, isEditing);
imageVideoContainer = new Container(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_SCALE)) {
protected Dimension calcPreferredSize() {
return new Dimension(Display.getInstance().getDisplayWidth(), Display.getInstance().getDisplayWidth());
}
};
_mPlayer = new MediaPlayer();
setupWidgetFromProperty();
}
#Override
public void renderEdit() {
//super.initLayout();
super.setEnabled(true);
}
public void renderSummary() {
//super.initLayout();
super.setEnabled(false);
getIconContainer().remove();
revalidate();
}
#Override
public void renderView() {
//find the
//super.initLayout();
super.setEnabled(false);
getIconContainer().remove();
revalidate();
}
#Override
public void setupWidgetFromProperty() {
super.setupWidgetFromProperty();
String videoFile = documentElement.getVideoFileFromValue(documentElement.getPropertyValue());
if (videoFile != null) {
try {
Media video = MediaManager.createMedia(videoFile, true);
if (_mPlayer == null) {
_mPlayer = new MediaPlayer();
}
_mPlayer.setDataSource(videoFile);
_mPlayer.setAutoplay(true);
if (imageVideoContainer == null) {
imageVideoContainer = new Container(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_SCALE)) {
protected Dimension calcPreferredSize() {
return new Dimension(Display.getInstance().getDisplayWidth(), Display.getInstance().getDisplayWidth() );
}
};
}
getWidgetContainer().removeAll();
imageVideoContainer.add(BorderLayout.CENTER, _mPlayer);
imageVideoContainer.revalidate();
getWidgetContainer().add(imageVideoContainer);
getWidgetContainer().revalidate();
getWidgetContainer().repaint();
documentElement.setPropertyValue(videoFile);
} catch (Exception err) {
Log.e(err);
}
}
}
#Override
public void setupPropertyButtons() {
super.setupPropertyButtons();
//add a capture button and a browse button for gallery
//save captured picture and put the URL value in the propertyValue
final Widget _this = this;
_captureButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//open the capture button and take a video
String photoFile = Capture.captureVideo();
if (photoFile != null) {
try {
_mPlayer.setDataSource(photoFile);
_mPlayer.setAutoplay(false);
_mPlayer.revalidate();
_mPlayer.repaint();
imageVideoContainer.revalidate();
_this.revalidate();
documentElement.setPropertyValue(photoFile);
} catch (Exception err) {
Log.e(err);
}
}
}
});
_captureButton.setText("");
getIconContainer().add(_captureButton);
getIconContainer().revalidate();
getIconContainer().repaint();
getLabelContainer().repaint();
_findButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
Display.getInstance().openGallery(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ev) {
if (ev != null && ev.getSource() != null) {
String file = (String) ev.getSource();
try {
_mPlayer.setDataSource(file);
_mPlayer.setAutoplay(false);
_mPlayer.revalidate();
_mPlayer.repaint();
imageVideoContainer.revalidate();
imageVideoContainer.repaint();
_this.revalidate();
documentElement.setPropertyValue(file);
} catch (Exception err) {
Log.e(err);
}
}
}
}, Display.GALLERY_VIDEO);
}
});
_findButton.setText("");
getIconContainer().add(_findButton);
getIconContainer().revalidate();
getIconContainer().repaint();
getLabelContainer().repaint();
this.revalidate();
}
public void render(boolean editing) {
if (isEditing) {
renderEdit();
}
if (!isEditing) {
renderSummary();
}
}
}
`
What am I doing wrong or show me working code sample to achieve what I am trying to achieve.

My app crashes when i try to launch it

My app crashes when i tried to launch it.
I'm trying to learn how to make the app cycle through an array of strings and then repeats once everything has been picked. This is done with a press of a button. But it crashes when i try to launch it on my phone. Any suggestions or help would be greatly appreciated.
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MainActivity extends Activity {
TextView textOne = (TextView) findViewById(R.id.TextView1);
Button pushMe = (Button) findViewById(R.id.button);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pushMe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
textOne.setText(pick());
}
List<String> myStrings = new ArrayList<String>() {{
add("b");
add("a");
add("z");
add("y");
add("x");
}};
List<String> dupeList = new ArrayList<String>() {{
addAll(myStrings);
}};
Random r = new Random();
public String pick() {
String retval = "";
int pos;
switch (dupeList.size()) {
case 1:
retval = dupeList.get(0);
dupeList.clear();
dupeList.addAll(myStrings);
return retval;
default:
pos = r.nextInt(dupeList.size());
retval = dupeList.get(pos);
dupeList.remove(pos);
return retval;
}
}
});
}
#Override
public boolean onCreateOptionsMenu (Menu menu){
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
//this opens another activity
#Override
public boolean onOptionsItemSelected (MenuItem item){
switch (item.getItemId()) {
case R.id.RulesButton:
startActivity(new Intent(this, RulesActivity.class));
break;
}
return true;
}
}
found the problem. i just needed to change "TextView textOne...." to "final TextView textOne..." and place it below the onCreate method.
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textOne = (TextView) findViewById(R.id.TextView1);
Button pushMe = (Button) findViewById(R.id.button);
pushMe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
textOne.setText(pick());
}
List<String> myStrings = new ArrayList<String>() {{
add("b");
add("a");
add("z");
add("y");
add("x");
}};
List<String> dupeList = new ArrayList<String>() {{
addAll(myStrings);
}};
Random r = new Random();
public String pick() {
String retval = "";
int pos;
switch (dupeList.size()) {
case 1:
retval = dupeList.get(0);
dupeList.clear();
dupeList.addAll(myStrings);
return retval;
default:
pos = r.nextInt(dupeList.size());
retval = dupeList.get(pos);
dupeList.remove(pos);
return retval;
}
}
});
}
#Override
public boolean onCreateOptionsMenu (Menu menu){
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
//this opens another activity
#Override
public boolean onOptionsItemSelected (MenuItem item){
switch (item.getItemId()) {
case R.id.RulesButton:
startActivity(new Intent(this, RulesActivity.class));
break;
}
return true;
}
}
Just for information as you are new in Android logs will help you more.
Log will be in eclipse tool (developing tool you are using) not on your device.
Change perspective to DDMS -> Go to LogCat.
There will be error logs in it.

ArrayIndexOutOfBoundsException error when writing to a tag

I followed a tutorial on how to write a NDEF message to a tag. and now when I run it. it detects the tag and when I press the button to write the message and the app crashes. it gives me JAVA.LANG.ArrayIndexOutOfBoundsException can someone please help me on what I'm doing wrong.
this is the error I see in logcat.
any help is appreciated.
Here is the code:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class WriteMessage extends Activity {
NfcAdapter adapter;
PendingIntent pendingIntent;
IntentFilter writeTagFilters[];
boolean writeMode;
Tag myTag;
Context ctx;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_write_message);
ctx=this;
Button WriteTag = (Button) findViewById (R.id.WriteTag);
final TextView Message = (TextView) findViewById (R.id.MessageBox);
WriteTag.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
if(myTag==null){
Toast.makeText(ctx, "Error_detected", Toast.LENGTH_LONG).show();
}else{
write(Message.getText().toString(), myTag);
Toast.makeText(ctx, "Ok_Writing", Toast.LENGTH_LONG).show();
}
}catch(IOException e){
Toast.makeText(ctx, "Error_Writing", Toast.LENGTH_LONG).show();
e.printStackTrace();
//} catch(FormatException e){
e.printStackTrace();
} catch (FormatException e) {
// TODO Auto-generated catch block
Toast.makeText(ctx, "Error_Writing", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
adapter = NfcAdapter.getDefaultAdapter(this);
pendingIntent = PendingIntent.getActivity(this, 0, new Intent (this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter tagDetected = new IntentFilter (NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
writeTagFilters = new IntentFilter[] {tagDetected };
}
private void write(String text, Tag myTag)throws IOException, FormatException {
NdefRecord[] records = {createRecord(text)};
NdefMessage message = new NdefMessage(records);
Ndef ndef = Ndef.get(myTag);
ndef.connect();
ndef.writeNdefMessage(message);
ndef.close();
}
private NdefRecord createRecord (String text ) throws UnsupportedEncodingException {
String lang = "en";
byte[] textBytes = text.getBytes();
byte[] langBytes = lang.getBytes("US-ASCII");
int langLength = langBytes.length;
int textLength = textBytes.length;
byte[] payload = new byte [1+ langLength + textLength ];
payload[0] = (byte) langLength;
System.arraycopy(langBytes, 0, payload, 1, langLength);
System.arraycopy(langBytes, 0, payload, 1 + langLength, textLength);
NdefRecord recordNFC = new NdefRecord (NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);
return recordNFC;
}
#Override
protected void onNewIntent(Intent intent){
if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Toast.makeText(this, "ok_detection" + myTag.toString(), Toast.LENGTH_LONG ).show();
}
}
#Override
public void onPause(){
super.onPause();
WriteModeOff();
}
#Override
public void onResume(){
super.onResume();
WriteModeOn();
}
private void WriteModeOn(){
writeMode = true;
adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null);
}
private void WriteModeOff(){
writeMode = false;
adapter.disableForegroundDispatch(this);
}
}
Looks like createRecord() is copying langBytes into payload twice instead of copying textBytes, but with the length of textBytes. If textBytes is longer than langBytes, it won't find enough data to copy from the source.
See the documentation on arraycopy.

Resources