作为我刚接触Java的人,我自己制作了这些代码,并从其他来源学到了一些部分。我想将所有联系人信息备份到主存储器或SD卡中的.vcf文件(无关紧要),最后将其检索回来。但在此代码中,您只能看到备份部分:
public class MainActivity extends Activity
{
Cursor cursor;
ArrayList<String> vCard ;
String vfile;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vfile = "Contacts" + "_" + System.currentTimeMillis()+".vcf";
getVcardString();
}
private void getVcardString() {
vCard = new ArrayList<String>();
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if(cursor!=null&&cursor.getCount()>0)
{
cursor.moveToFirst();
for(int i =0;i<cursor.getCount();i++)
{
get(cursor);
Log.d("TAG", "Contact "+(i+1)+"VcF String is"+vCard.get(i));
cursor.moveToNext();
}
}
else
{
Log.d("TAG", "No Contacts in Your Phone");
}
}
public void get(Cursor cursor)
{
String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd;
try {
fd = this.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] buf = new byte[(int) fd.getDeclaredLength()];
fis.read(buf);
String vcardstring= new String(buf);
vCard.add(vcardstring);
String storage_path = Environment.getRootDirectory().toString() + File.separator + vfile;
FileOutputStream mFileOutputStream = new FileOutputStream(storage_path, false);
mFileOutputStream.write(vcardstring.toString().getBytes());
} catch (Exception e1)
{
e1.printStackTrace();
}
}
}
问题是代码不起作用,并且没有异常或任何错误。我搜索了根目录和所有文件夹,但没有.vcf文件。我的权限是:<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
我在API 17和24上运行了这个。任何想法为什么它不起作用?
答案 0 :(得分:0)
public void shoro(View v)抛出IOException {
Toast.makeText(this,"ok2",Toast.LENGTH_SHORT).show();
vfile = "Contacts" + "_" + System.currentTimeMillis()+".vcf";
vCard = new ArrayList<String>();
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if(cursor!=null&&cursor.getCount()>0)
{
Toast.makeText(this,"ok3",Toast.LENGTH_SHORT).show();
cursor.moveToFirst();
for(int i =0;i<cursor.getCount();i++)
{
get(cursor);
Log.d("TAG", "Contact "+(i+1)+"VcF String is"+vCard.get(i));
cursor.moveToNext();
}
}
else
{
Log.d("TAG", "No Contacts in Your Phone");
}
}
public void get(Cursor cursor) throws IOException {
Toast.makeText(this,"ok4",Toast.LENGTH_SHORT).show();
String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd;
fd = this.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] buf = new byte[(int) fd.getDeclaredLength()];
fis.read(buf);
String vcardstring= new String(buf);
vCard.add(vcardstring);
String storage_path = Environment.getDataDirectory().toString() + File.separator + vfile;
FileOutputStream mFileOutputStream = new FileOutputStream(storage_path, false);
mFileOutputStream.write(vcardstring.toString().getBytes());
}
首先看看那些Toasts,我让他们找出应用程序继续前行。很奇怪第一次,我问这些问题,我忘了给我的联系人添加电话号码(我有3个联系人进行测试),当我运行应用程序时(当我没有添加号码)时,应用程序继续运行,没有任何错误,但是没有工作(我们之前的谈话是关于这个,我的错:D)。然后,当我检查Toasts时,我发现该应用程序永远不会到达&#34; ok3&#34;吐司。之后,当我向联系人添加号码时,现在应用程序甚至无法运行。当我按下按钮时,它会崩溃并关闭。我将运行中的线条放在下面链接的记事本中(API 17):
https://ufile.io/i3gu4
我在API 24和21上测试了这个,但同样的问题。可能是什么问题?
答案 1 :(得分:0)
public void terp(View v)抛出IOException { Toast.makeText(此, “OK”,Toast.LENGTH_SHORT).show();
DB::table('users')->select('FirstName')->get();
shoro()是主要功能。
答案 2 :(得分:0)
Android不允许您在 Environment.getDataDirectoy()中创建文件。这指向/ data文件夹,供系统使用。如果要使用内部存储,可以使用/ data / data / your_app_package存储。要获得访问权限,您只需更改代码的一行 -
String storage_path = getFilesDir().getAbsolutePath() + File.separator + vfile;
要验证您的文件是否已创建,您可以执行以下步骤
如果要使用外部存储,请使用 Environment.getExternalStorageDirectory()方法。
要了解Android设备中的不同路径,请查看here
更新1 讨论后,这里是更新的代码。有多个问题 - 1)我们需要接受多个权限,并为API&gt; = 23满足所有权限 2)AssetFileDescriptor为API提供长度为-1&gt; = 24 因此代码破灭了。
所以在2个地方改变 - 改变你的获取方法 -
public void get(Cursor cursor) throws IOException {
Toast.makeText(this,"ok4",Toast.LENGTH_SHORT).show();
String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri vCardUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor assetFileDescriptor;
String vcardstring="";
if (Build.VERSION.SDK_INT >= 24) {
FileInputStream inputStream=null;
byte[] buffer = new byte[4096];
ByteArrayOutputStream ous = null;
try {
assetFileDescriptor = this.getContentResolver().openAssetFileDescriptor(vCardUri, "r");
if (assetFileDescriptor != null) {
ous = new ByteArrayOutputStream();
int read = 0;
inputStream = assetFileDescriptor.createInputStream();
while ((read = inputStream.read(buffer)) != -1) {
ous.write(buffer, 0, read);
}
}
} catch (FileNotFoundException e) {
Log.e(TAG, "Vcard for the contact " + lookupKey + " not found", e);
} catch (IOException e) {
Log.e(TAG, "Problem creating stream from the assetFileDescriptor.", e);
}finally {
try {
if (ous != null)
ous.close();
} catch (IOException e) {
}
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
}
}
vcardstring= new String(ous.toByteArray());
}else{
assetFileDescriptor = this.getContentResolver().openAssetFileDescriptor(vCardUri, "r");
FileInputStream fis = assetFileDescriptor.createInputStream();
byte[] buf = new byte[(int) assetFileDescriptor.getDeclaredLength()];
fis.read(buf);
vcardstring= new String(buf);
}
vCard.add(vcardstring);
Log.i("File Kapil", "path "+getFilesDir().getAbsolutePath().toString());
String storage_path = getFilesDir().getAbsolutePath() + File.separator + vfile;
FileOutputStream mFileOutputStream = new FileOutputStream(storage_path, false);
mFileOutputStream.write(vcardstring.toString().getBytes());
}
对于请求权限更改 -
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.WRITE_CONTACTS)
== PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.READ_CONTACTS)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
return true;
} else {
Log.v(TAG,"Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_CONTACTS}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 0:
boolean isPerpermissionForAllGranted = false;
if (grantResults.length > 0 && permissions.length==grantResults.length) {
for (int i = 0; i < permissions.length; i++){
if (grantResults[i] == PackageManager.PERMISSION_GRANTED){
isPerpermissionForAllGranted=true;
}else{
isPerpermissionForAllGranted=false;
}
}
Log.e("value", "Permission Granted, Now you can use local drive .");
} else {
isPerpermissionForAllGranted=true;
Log.e("value", "Permission Denied, You cannot use local drive .");
}
if(isPerpermissionForAllGranted){
shoro();
}
break;
}
}
在你的Shoro方法中改变代码 -
public void shoro(){
boolean isPermissionGiven = isStoragePermissionGranted();
Toast.makeText(this,"ok2",Toast.LENGTH_SHORT).show();
if (isPermissionGiven){
// Do stuff
}
}
可以找到完整的代码 - Here